On March 21, 2016 6:55:28 PM GMT+01:00, Marek Polacek <pola...@redhat.com> wrote: >This PR points out to a GC problem: when we freed a duplicate typedef, >we were >leaving its type in the variants list, with its TYPE_NAME still >pointing to the >now-freed TYPE_DECL, leading to a crash. I was lucky to discover that >the >exact same problem was fixed in November for the C++ FE, so I could >just follow >suit here. And because that change didn't add a new testcase, I'm >putting the >new test into c-c++-common/. > >Bootstrapped/regtested on x86_64-linux, ok for trunk/5?
But IIRC this will drop the aligned attribute effect as that applied to the new type? Richard. >2016-03-21 Marek Polacek <pola...@redhat.com> > > PR c/70297 > * c-decl.c (merge_decls): When combining typedefs, remove the new > type from the variants list. > > * c-c++-common/pr70297.c: New test. > >diff --git gcc/c/c-decl.c gcc/c/c-decl.c >index bab4715..98d7f2a 100644 >--- gcc/c/c-decl.c >+++ gcc/c/c-decl.c >@@ -2358,6 +2358,26 @@ merge_decls (tree newdecl, tree olddecl, tree >newtype, tree oldtype) > DECL_ATTRIBUTES (newdecl) > = targetm.merge_decl_attributes (olddecl, newdecl); > >+ /* For typedefs use the old type, as the new type's DECL_NAME points >+ at newdecl, which will be ggc_freed. */ >+ if (TREE_CODE (newdecl) == TYPE_DECL) >+ { >+ newtype = oldtype; >+ >+ /* And remove the new type from the variants list. */ >+ if (TYPE_NAME (TREE_TYPE (newdecl)) == newdecl) >+ { >+ tree remove = TREE_TYPE (newdecl); >+ for (tree t = TYPE_MAIN_VARIANT (remove); ; >+ t = TYPE_NEXT_VARIANT (t)) >+ if (TYPE_NEXT_VARIANT (t) == remove) >+ { >+ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (remove); >+ break; >+ } >+ } >+ } >+ > /* Merge the data types specified in the two decls. */ > TREE_TYPE (newdecl) > = TREE_TYPE (olddecl) >diff --git gcc/testsuite/c-c++-common/pr70297.c >gcc/testsuite/c-c++-common/pr70297.c >index e69de29..bc078c8 100644 >--- gcc/testsuite/c-c++-common/pr70297.c >+++ gcc/testsuite/c-c++-common/pr70297.c >@@ -0,0 +1,10 @@ >+/* PR c/70297 */ >+/* { dg-do compile } */ >+/* { dg-options "-g" } */ >+ >+typedef unsigned int uint32_t; >+typedef uint32_t T; >+typedef uint32_t T __attribute__((aligned(4))); >+struct S { >+ T *t; >+}; > > Marek