diff options
author | Marek Polacek <polacek@redhat.com> | 2016-03-31 14:29:15 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2016-03-31 14:29:15 +0000 |
commit | 5fde6a45eb888e7f8f48e0b015960f223dd7602a (patch) | |
tree | da1c9585f557c7e34eea4677a004d3d1368dc0de /gcc/c | |
parent | 97eb24c42a5d82617e576165867dd6678b6b1262 (diff) | |
download | gcc-5fde6a45eb888e7f8f48e0b015960f223dd7602a.zip gcc-5fde6a45eb888e7f8f48e0b015960f223dd7602a.tar.gz gcc-5fde6a45eb888e7f8f48e0b015960f223dd7602a.tar.bz2 |
re PR c/70297 (GCC Segfaults when using -g3)
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
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c/c-decl.c | 29 |
2 files changed, 34 insertions, 0 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index c8cb022..b52b414 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 bab4715..0dd2121 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) |