Currently, the way gengtype works it scans the list of source files
with front end files at the end, and pushes data structures onto a
stack.  It then processes the stack in LIFO order, so that data
structures from front ends are handled first.  As a result, if a GTY
data structure in a front end depends on tree_node, gengtype happily
puts gt_ggc_mx(tree_node*&) in a front end file, leading to link
errors on all other front ends.

This patch avoids this problem by appending to the list of data
structures so that they are processed in FIFO order, and so tree_node
gets handled in gtype-desc.o.

Tested x86_64-pc-linux-gnu, OK for trunk?
commit 487a1c95c0d3169b2041942ff4f8d71c9ff689eb
Author: Jason Merrill <ja...@redhat.com>
Date:   Wed Oct 26 23:12:23 2016 -0400

            * gengtype.c (new_structure): Append to structures list.
    
            (find_structure): Likewise.

diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 760f985..a579547 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -744,10 +744,11 @@ new_structure (const char *name, enum typekind kind, 
struct fileloc *pos,
   type_p s = NULL;
   lang_bitmap bitmap = get_lang_bitmap (pos->file);
   bool isunion = (kind == TYPE_UNION);
+  type_p *p = &structures;
 
   gcc_assert (union_or_struct_p (kind));
 
-  for (si = structures; si != NULL; si = si->next)
+  for (si = structures; si != NULL; p = &si->next, si = *p)
     if (strcmp (name, si->u.s.tag) == 0 && UNION_P (si) == isunion)
       {
        type_p ls = NULL;
@@ -793,8 +794,7 @@ new_structure (const char *name, enum typekind kind, struct 
fileloc *pos,
       type_count++;
       s = XCNEW (struct type);
       s->state_number = -type_count;
-      s->next = structures;
-      structures = s;
+      *p = s;
     }
 
   if (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap))
@@ -829,21 +829,20 @@ find_structure (const char *name, enum typekind kind)
 {
   type_p s;
   bool isunion = (kind == TYPE_UNION);
+  type_p *p = &structures;
 
   gcc_assert (kind == TYPE_UNDEFINED || union_or_struct_p (kind));
 
-  for (s = structures; s != NULL; s = s->next)
+  for (s = structures; s != NULL; p = &s->next, s = *p)
     if (strcmp (name, s->u.s.tag) == 0 && UNION_P (s) == isunion)
       return s;
 
   type_count++;
   s = XCNEW (struct type);
-  s->next = structures;
   s->state_number = -type_count;
-  structures = s;
   s->kind = kind;
   s->u.s.tag = name;
-  structures = s;
+  *p = s;
   return s;
 }
 

Reply via email to