On Fri, Apr 12, 2019 at 02:46:19PM -0400, Jason Merrill wrote: > On 4/12/19 3:19 AM, Jakub Jelinek wrote: > > 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). > > If the typedef is a duplicate, the type ought to be garbage as well, no?
I'd hope so. So, would you prefer this instead, where instead of changing the TYPE_NAME of the type we assert it has no variants? I was just worried there might be variants, but duplicate_decls should happen immediately on the typedef, so there shouldn't be time to create the variants. Tried typedef const unsigned int a __attribute__ ((__aligned__(8), __may_alias__)); typedef const unsigned int a __attribute__ ((__aligned__(8), __may_alias__)); and it works too. 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 assert it has no variants. 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 assert it has no variants. testsuite/ * c-c++-common/pr89933.c: New test. --- gcc/c/c-decl.c.jj 2019-04-11 17:25:08.873026245 +0200 +++ gcc/c/c-decl.c 2019-04-12 21:48:15.815779025 +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) + gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE); + 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-11 17:25:08.664029678 +0200 +++ gcc/cp/decl.c 2019-04-12 21:48:28.926563001 +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) + gcc_assert (TYPE_NEXT_VARIANT (remove) == NULL_TREE); + 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-12 21:47:46.189267166 +0200 +++ gcc/testsuite/c-c++-common/pr89933.c 2019-04-12 21:47:46.189267166 +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