diff options
-rw-r--r-- | gcc/c/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c/c-decl.c | 29 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/decl.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr70297.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/typedef-redecl.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/typedef-redecl2.c | 13 |
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"); |