https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114493
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> --- This doesn't ICE in C++, because the C++ FE forcibly updates the corresponding pointer types in: #0 fixup_may_alias (klass=<record_type 0x7fffea2dec78 S>) at ../../gcc/cp/class.cc:2328 #1 0x0000000000456835 in fixup_attribute_variants (t=<record_type 0x7fffea2dec78 S>) at ../../gcc/cp/class.cc:2354 #2 0x00000000006f3024 in cp_parser_class_head (parser=0x7fffea2dea80, nested_name_specifier_p=0x7fffffffd5ff) at ../../gcc/cp/parser.cc:27831 /* KLASS is a class that we're applying may_alias to after the body is parsed. Fixup any POINTER_TO and REFERENCE_TO types. The canonical type(s) will be implicitly updated. */ static void fixup_may_alias (tree klass) { tree t, v; for (t = TYPE_POINTER_TO (klass); t; t = TYPE_NEXT_PTR_TO (t)) for (v = TYPE_MAIN_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v)) TYPE_REF_CAN_ALIAS_ALL (v) = true; for (t = TYPE_REFERENCE_TO (klass); t; t = TYPE_NEXT_REF_TO (t)) for (v = TYPE_MAIN_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v)) TYPE_REF_CAN_ALIAS_ALL (v) = true; } Now, fixup_attribute_variants also does: for (variants = TYPE_NEXT_VARIANT (t); variants; variants = TYPE_NEXT_VARIANT (variants)) { /* These are the two fields that check_qualified_type looks at and are affected by attributes. */ TYPE_ATTRIBUTES (variants) = attrs; unsigned valign = align; if (TYPE_USER_ALIGN (variants)) valign = MAX (valign, TYPE_ALIGN (variants)); else TYPE_USER_ALIGN (variants) = user_align; SET_TYPE_ALIGN (variants, valign); TYPE_PACKED (variants) = packed; if (may_alias) fixup_may_alias (variants); } I think the TYPE_ATTRIBUTES update isn't needed, because decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE); should update the variants already: 984 TYPE_ATTRIBUTES (*anode) = r; 985 /* If this is the main variant, also push the attributes 986 out to the other variants. */ 987 if (*anode == TYPE_MAIN_VARIANT (*anode)) 988 { 989 for (tree variant = *anode; variant; 990 variant = TYPE_NEXT_VARIANT (variant)) 991 { 992 if (TYPE_ATTRIBUTES (variant) == old_attrs) 993 TYPE_ATTRIBUTES (variant) 994 = TYPE_ATTRIBUTES (*anode); 995 else if (!find_same_attribute 996 (attr, TYPE_ATTRIBUTES (variant))) 997 TYPE_ATTRIBUTES (variant) = tree_cons 998 (name, args, TYPE_ATTRIBUTES (variant)); 999 } 1000 } Seems finish_struct doesn't actually call layout_type on the type variants, wonder what does that, but I'd think that stuff like TYPE_USER_ALIGN, TYPE_ALIGN would be finalized when layout_type is performed for those. TYPE_PACKED is apparently done in finish_record_layout even for the variants (called from layout_type).