From: Jakub Jelinek Date: Fri, 30 Aug 2019 12:38:31 +0000 (+0200) Subject: backport: re PR c++/90108 (ICE: Segmentation fault (in c_tree_chain_next)) X-Git-Tag: releases/gcc-7.5.0~213 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=79797c978183ab550eb109ea4e70ad4d214aa482;p=thirdparty%2Fgcc.git backport: re PR c++/90108 (ICE: Segmentation fault (in c_tree_chain_next)) Backported from mainline 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. * 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: r275150 --- diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index a861feeac2ee..394457213f78 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,6 +1,13 @@ 2019-08-30 Jakub Jelinek Backported from mainline + 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 11c63af89ed7..964d5f1a2d22 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -2349,7 +2349,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 742b0e428440..9712503fe9e4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,6 +1,13 @@ 2019-08-30 Jakub Jelinek Backported from mainline + 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-12 Jakub Jelinek PR c/89933 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 1ad6ad8fae48..56e4c31e242e 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2131,7 +2131,24 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) { 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 978d725437ec..9b51773a0d31 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2019-08-30 Jakub Jelinek Backported from mainline + 2019-04-19 Jakub Jelinek + + PR c++/90108 + * c-c++-common/pr90108.c: New test. + 2019-04-16 Jakub Jelinek PR rtl-optimization/90082 diff --git a/gcc/testsuite/c-c++-common/pr90108.c b/gcc/testsuite/c-c++-common/pr90108.c new file mode 100644 index 000000000000..fa5b8461aaea --- /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__));