From e7178413f46ac98975bd4b83e073c931b418205d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 19 Apr 2019 10:24:05 +0200 Subject: [PATCH] re PR c++/90108 (ICE: Segmentation fault (in c_tree_chain_next)) PR c++/90108 * c-decl.c (merge_decls): If remove is main variant and DECL_ORIGINAL_TYPE is some other type, remove a DECL_ORIGINAL_TYPE variant that has newdecl as TYPE_NAME if any. * decl.c (duplicate_decls): If remove is main variant and DECL_ORIGINAL_TYPE is some other type, remove a DECL_ORIGINAL_TYPE variant that has newdecl as TYPE_NAME if any. * c-c++-common/pr90108.c: New test. From-SVN: r270453 --- gcc/c/ChangeLog | 7 +++++++ gcc/c/c-decl.c | 19 ++++++++++++++++++- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/decl.c | 19 ++++++++++++++++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/c-c++-common/pr90108.c | 6 ++++++ 6 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/pr90108.c diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index c8e5e1a..27660b9 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,10 @@ +2019-04-19 Jakub Jelinek + + PR c++/90108 + * c-decl.c (merge_decls): If remove is main variant and + DECL_ORIGINAL_TYPE is some other type, remove a DECL_ORIGINAL_TYPE + variant that has newdecl as TYPE_NAME if any. + 2019-04-12 Jakub Jelinek PR c/89933 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index ef9b874..c8e7cd0 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -2513,7 +2513,24 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) { tree remove = TREE_TYPE (newdecl); if (TYPE_MAIN_VARIANT (remove) == remove) - gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE); + { + gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE); + /* If remove is the main variant, no need to remove that + from the list. One of the DECL_ORIGINAL_TYPE + variants, e.g. created for aligned attribute, might still + refer to the newdecl TYPE_DECL though, so remove that one + in that case. */ + if (DECL_ORIGINAL_TYPE (newdecl) + && DECL_ORIGINAL_TYPE (newdecl) != remove) + for (tree t = TYPE_MAIN_VARIANT (DECL_ORIGINAL_TYPE (newdecl)); + t; t = TYPE_MAIN_VARIANT (t)) + if (TYPE_NAME (TYPE_NEXT_VARIANT (t)) == newdecl) + { + TYPE_NEXT_VARIANT (t) + = TYPE_NEXT_VARIANT (TYPE_NEXT_VARIANT (t)); + break; + } + } else for (tree t = TYPE_MAIN_VARIANT (remove); ; t = TYPE_NEXT_VARIANT (t)) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7bb464f..9c1c49b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-04-19 Jakub Jelinek + + PR c++/90108 + * decl.c (duplicate_decls): If remove is main variant and + DECL_ORIGINAL_TYPE is some other type, remove a DECL_ORIGINAL_TYPE + variant that has newdecl as TYPE_NAME if any. + 2019-04-18 Jason Merrill PR c++/87554 - ICE with extern template and reference member. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 420d6d8..21b4cc6 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2133,7 +2133,24 @@ next_arg:; { tree remove = TREE_TYPE (newdecl); if (TYPE_MAIN_VARIANT (remove) == remove) - gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE); + { + gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE); + /* If remove is the main variant, no need to remove that + from the list. One of the DECL_ORIGINAL_TYPE + variants, e.g. created for aligned attribute, might still + refer to the newdecl TYPE_DECL though, so remove that one + in that case. */ + if (tree orig = DECL_ORIGINAL_TYPE (newdecl)) + if (orig != remove) + for (tree t = TYPE_MAIN_VARIANT (orig); t; + t = TYPE_MAIN_VARIANT (t)) + if (TYPE_NAME (TYPE_NEXT_VARIANT (t)) == newdecl) + { + TYPE_NEXT_VARIANT (t) + = TYPE_NEXT_VARIANT (TYPE_NEXT_VARIANT (t)); + break; + } + } else for (tree t = TYPE_MAIN_VARIANT (remove); ; t = TYPE_NEXT_VARIANT (t)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 451f190..15e1d14 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-04-19 Jakub Jelinek + + PR c++/90108 + * c-c++-common/pr90108.c: New test. + 2019-04-18 Richard Sandiford PR middle-end/85164 diff --git a/gcc/testsuite/c-c++-common/pr90108.c b/gcc/testsuite/c-c++-common/pr90108.c new file mode 100644 index 0000000..fa5b846 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr90108.c @@ -0,0 +1,6 @@ +/* PR c++/90108 */ +/* { dg-do compile } */ +/* { dg-options "--param ggc-min-heapsize=0" } */ + +typedef unsigned int a __attribute__ ((__aligned__(8), __may_alias__)); +typedef unsigned int a __attribute__ ((__aligned__(8), __may_alias__)); -- 2.7.4