diff options
author | Robert Bradshaw <robertwb@math.washington.edu> | 2008-11-25 14:04:41 -0800 |
---|---|---|
committer | Robert Bradshaw <robertwb@math.washington.edu> | 2008-11-25 14:04:41 -0800 |
commit | f61e9124c9f485e429aecda28427e10a8a48e426 (patch) | |
tree | ade887ee83ff8ade7e24bbc274d5bbdc72186eaf | |
parent | a81796ca29538714ff5a86a512fe2bd3587e159c (diff) | |
download | cython-0.10.2.tar.gz |
Fix gcc crash on recursive typedef struct0.10.2
Won't break existing code, only makes bad code compile now.
-rw-r--r-- | Cython/Compiler/Nodes.py | 19 | ||||
-rw-r--r-- | tests/compile/ctypedefstruct.pyx | 3 |
2 files changed, 22 insertions, 0 deletions
diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index bd583d80b..404b2c4ac 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -784,11 +784,30 @@ class CStructOrUnionDefNode(StatNode): self.entry = env.declare_struct_or_union( self.name, self.kind, scope, self.typedef_flag, self.pos, self.cname, visibility = self.visibility) + need_typedef_indirection = False if self.attributes is not None: if self.in_pxd and not env.in_cinclude: self.entry.defined_in_pxd = 1 for attr in self.attributes: attr.analyse_declarations(env, scope) + for attr in scope.var_entries: + type = attr.type + while type.is_array: + type = type.base_type + if type == self.entry.type: + error(attr.pos, "Struct cannot contain itself as a member.") + if self.typedef_flag: + while type.is_ptr: + type = type.base_type + if type == self.entry.type: + need_typedef_indirection = True + if need_typedef_indirection and self.visibility != 'extern': + # C can't handle typedef structs that refer to themselves. + struct_entry = self.entry + cname = env.new_const_cname() + self.entry = env.declare_typedef(self.name, struct_entry.type, self.pos, cname = self.cname, visibility='ignore') + struct_entry.type.typedef_flag = False + struct_entry.cname = struct_entry.type.cname = env.new_const_cname() def analyse_expressions(self, env): pass diff --git a/tests/compile/ctypedefstruct.pyx b/tests/compile/ctypedefstruct.pyx index b52c215ad..825583ecd 100644 --- a/tests/compile/ctypedefstruct.pyx +++ b/tests/compile/ctypedefstruct.pyx @@ -7,3 +7,6 @@ cdef order order1 order1.spam = 7 order1.eggs = 2 +ctypedef struct linked: + int a + linked *next |