Hi! In r234626 Marek has added code to remove TREE_TYPE (newdecl) from its variant list for typedefs, because we'll ggc_free the TYPE_NAME of that type. Unfortunately, that code will ICE if TREE_TYPE (newdecl) is its own TYPE_MAIN_VARIANT. This can happen if due to attributes the newdecl's type has been build_distinct_type_copy created but hasn't been type_hash_canon merged (which we do for a few attributes like aligned, but certainly don't do it for most other attributes). In the likely case there are no variants for that type yet, there is just nothing to remove. If there are some (in theory), the options are do what the following patch does, keep the type in the variant list as the main variant, just change the TYPE_NAME, so that it doesn't refer to ggc_freed TYPE_DECL, or try to pick up some other type as the main variant and adjust the whole variant list (I don't think the C/C++ FEs unlike Ada FE like e.g. qualified types as main variant though).
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Though, maybe we could do that TYPE_NAME (remove) = olddecl; unconditionally and only do the removal from variant list conditionally. Would you prefer that? 2019-04-12 Jakub Jelinek <ja...@redhat.com> PR c/89933 c/ * c-decl.c (merge_decls): When newdecl's type is its main variant, don't try to remove it from the variant list, but instead change TYPE_NAME to olddecl. cp/ * decl.c (duplicate_decls): When newdecl's type is its main variant, don't try to remove it from the variant list, but instead change TYPE_NAME to olddecl. testsuite/ * c-c++-common/pr89933.c: New test. --- gcc/c/c-decl.c.jj 2019-03-20 12:24:57.896298849 +0100 +++ gcc/c/c-decl.c 2019-04-11 16:43:48.437746631 +0200 @@ -2512,13 +2512,16 @@ merge_decls (tree newdecl, tree olddecl, 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; - } + if (TYPE_MAIN_VARIANT (remove) == remove) + TYPE_NAME (remove) = olddecl; + else + 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; + } } } --- gcc/cp/decl.c.jj 2019-04-09 15:18:36.860833102 +0200 +++ gcc/cp/decl.c 2019-04-11 16:46:40.176923681 +0200 @@ -2132,13 +2132,16 @@ next_arg:; 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; - } + if (TYPE_MAIN_VARIANT (remove) == remove) + TYPE_NAME (remove) = olddecl; + else + 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; + } } } else if (merge_attr) --- gcc/testsuite/c-c++-common/pr89933.c.jj 2019-04-11 16:50:13.808415292 +0200 +++ gcc/testsuite/c-c++-common/pr89933.c 2019-04-11 16:49:57.090689737 +0200 @@ -0,0 +1,5 @@ +/* PR c/89933 */ +/* { dg-do compile } */ + +typedef unsigned int a __attribute__ ((__aligned__(8), __may_alias__)); +typedef unsigned int a __attribute__ ((__aligned__(8), __may_alias__)); Jakub