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


Reply via email to