]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c/70297 (GCC Segfaults when using -g3)
authorMarek Polacek <polacek@redhat.com>
Thu, 31 Mar 2016 14:29:15 +0000 (14:29 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Thu, 31 Mar 2016 14:29:15 +0000 (14:29 +0000)
PR c/70297
* c-decl.c (merge_decls): Also set TYPE_ALIGN and TYPE_USER_ALIGN.

* decl.c (duplicate_decls): Also set TYPE_ALIGN and TYPE_USER_ALIGN.

* c-c++-common/pr70297.c: New test.
* g++.dg/cpp0x/typedef-redecl.C: New test.
* gcc.dg/typedef-redecl2.c: New test.

From-SVN: r234626

gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/pr70297.c [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/typedef-redecl.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/typedef-redecl2.c [new file with mode: 0644]

index c8cb0227e2a35f9ec319f147109f99fac3a2c559..b52b414478fd845be3ee9a2e7a73c655e28cd10a 100644 (file)
@@ -1,3 +1,8 @@
+2016-03-31  Marek Polacek  <polacek@redhat.com>
+
+       PR c/70297
+       * c-decl.c (merge_decls): Also set TYPE_ALIGN and TYPE_USER_ALIGN.
+
 2016-03-18  David Malcolm  <dmalcolm@redhat.com>
 
        PR c/70281
index bab471532354151019c6c4e8fb0700634412a005..0dd2121b86832155a404d7fa57044d8ed6b0fd4f 100644 (file)
@@ -2358,6 +2358,35 @@ 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)
+    {
+      /* But NEWTYPE might have an attribute, honor that.  */
+      tree tem = newtype;
+      newtype = oldtype;
+
+      if (TYPE_USER_ALIGN (tem))
+       {
+         if (TYPE_ALIGN (tem) > TYPE_ALIGN (newtype))
+           TYPE_ALIGN (newtype) = TYPE_ALIGN (tem);
+         TYPE_USER_ALIGN (newtype) = true;
+       }
+
+      /* 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)
index 96f02210aa91c42aaa96dbe6fcb8dc6211eca532..8aad906fc127ac4c9d0f0326462dbefdaf0ec7d6 100644 (file)
@@ -1,3 +1,8 @@
+2016-03-31  Marek Polacek  <polacek@redhat.com>
+
+       PR c/70297
+       * decl.c (duplicate_decls): Also set TYPE_ALIGN and TYPE_USER_ALIGN.
+
 2016-03-31  Richard Biener  <rguenther@suse.de>
 
        PR c++/70430
index cfae210da552c081e9e1ab86c755db949fa169e2..4730093da99f13584a6a1cfbb4a3d1d0e14af834 100644 (file)
@@ -2028,8 +2028,17 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
         at newdecl, which will be ggc_freed.  */
       if (TREE_CODE (newdecl) == TYPE_DECL)
        {
+         /* But NEWTYPE might have an attribute, honor that.  */
+         tree tem = TREE_TYPE (newdecl);
          newtype = oldtype;
 
+         if (TYPE_USER_ALIGN (tem))
+           {
+             if (TYPE_ALIGN (tem) > TYPE_ALIGN (newtype))
+               TYPE_ALIGN (newtype) = TYPE_ALIGN (tem);
+             TYPE_USER_ALIGN (newtype) = true;
+           }
+
          /* And remove the new type from the variants list.  */
          if (TYPE_NAME (TREE_TYPE (newdecl)) == newdecl)
            {
index aa0e17e1519f82ec1a97a621a56ef9114cebdea4..d1dd5ea7680e1a7bad07bc93914044e2c8029b46 100644 (file)
@@ -1,3 +1,10 @@
+2016-03-31  Marek Polacek  <polacek@redhat.com>
+
+       PR c/70297
+       * c-c++-common/pr70297.c: New test.
+       * g++.dg/cpp0x/typedef-redecl.C: New test.
+       * gcc.dg/typedef-redecl2.c: New test.
+
 2016-03-31  Jakub Jelinek  <jakub@redhat.com>
 
        PR rtl-optimization/70460
diff --git a/gcc/testsuite/c-c++-common/pr70297.c b/gcc/testsuite/c-c++-common/pr70297.c
new file mode 100644 (file)
index 0000000..70a4f15
--- /dev/null
@@ -0,0 +1,9 @@
+/* PR c/70297 */
+/* { dg-do compile } */
+/* { dg-options "-g" } */
+
+typedef int T;
+typedef int T __attribute__((aligned (4)));
+struct S {
+  T *t;
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/typedef-redecl.C b/gcc/testsuite/g++.dg/cpp0x/typedef-redecl.C
new file mode 100644 (file)
index 0000000..576c7ce
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c/70297
+// { dg-do compile { target c++11 } }
+
+#define N 64
+
+typedef int T;
+typedef int T __attribute__((aligned (N)));
+typedef int T __attribute__((aligned (N * 2)));
+typedef int T __attribute__((aligned (N)));
+typedef int T;
+
+static_assert (alignof (T) == N * 2, "N * 2");
diff --git a/gcc/testsuite/gcc.dg/typedef-redecl2.c b/gcc/testsuite/gcc.dg/typedef-redecl2.c
new file mode 100644 (file)
index 0000000..c2314c7
--- /dev/null
@@ -0,0 +1,13 @@
+/* PR c/70297 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+#define N 64
+
+typedef int T;
+typedef int T __attribute__((aligned (N)));
+typedef int T __attribute__((aligned (N * 2)));
+typedef int T __attribute__((aligned (N)));
+typedef int T;
+
+_Static_assert (_Alignof (T) == N * 2, "N * 2");