aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2016-03-31 14:29:15 +0000
committerMarek Polacek <polacek@redhat.com>2016-03-31 14:29:15 +0000
commite74a999040bdc75a696c438569937d4dc5049492 (patch)
treeda1c9585f557c7e34eea4677a004d3d1368dc0de
parentd7db186feed02c462fd82552bf79b74bf28f9851 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@234626 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/c/ChangeLog5
-rw-r--r--gcc/c/c-decl.c29
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/decl.c9
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/c-c++-common/pr70297.c9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/typedef-redecl.C12
-rw-r--r--gcc/testsuite/gcc.dg/typedef-redecl2.c13
8 files changed, 89 insertions, 0 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index c8cb0227e2a..b52b414478f 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -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
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index bab47153235..0dd2121b868 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -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)
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 96f02210aa9..8aad906fc12 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index cfae210da55..4730093da99 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index aa0e17e1519..d1dd5ea7680 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..70a4f15cd22
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr70297.c
@@ -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
index 00000000000..576c7ce0332
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/typedef-redecl.C
@@ -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
index 00000000000..c2314c78eaa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/typedef-redecl2.c
@@ -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");