Fix gcc crash on recursive typedef struct 0.10.2
authorRobert Bradshaw <robertwb@math.washington.edu>
Tue, 25 Nov 2008 22:04:41 +0000 (14:04 -0800)
committerRobert Bradshaw <robertwb@math.washington.edu>
Tue, 25 Nov 2008 22:04:41 +0000 (14:04 -0800)
Won't break existing code, only makes bad code compile now.

Cython/Compiler/Nodes.py
tests/compile/ctypedefstruct.pyx

index bd583d80b6ded0b320c279422cc1b8537c127acd..404b2c4ac9083376e933219e11af8266e4b941bd 100644 (file)
@@ -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
index b52c215ad7cdf73a9a41e747a84810b3b27161e8..825583ecd7339c93706a5c914cbab11dd029db5f 100644 (file)
@@ -7,3 +7,6 @@ cdef order order1
 order1.spam = 7
 order1.eggs = 2
 
+ctypedef struct linked:
+    int a
+    linked *next