On Wed, Aug 13, 2025 at 08:58:47PM -0400, Jason Merrill wrote: > > --- gcc/cp/tree.cc.jj 2025-07-27 23:31:09.750006633 +0200 > > +++ gcc/cp/tree.cc 2025-08-13 17:17:17.248836248 +0200 > > @@ -1186,7 +1186,13 @@ build_cplus_array_type (tree elt_type, t > > for (t = m; t; t = TYPE_NEXT_VARIANT (t)) > > if (TREE_TYPE (t) == elt_type > > && TYPE_NAME (t) == NULL_TREE > > - && TYPE_ATTRIBUTES (t) == NULL_TREE) > > + && TYPE_ATTRIBUTES (t) == NULL_TREE > > + && (!TYPE_USER_ALIGN (t) > > + || (TYPE_USER_ALIGN (elt_type) > > + && TYPE_ALIGN (t) == MAX (TYPE_ALIGN (elt_type), > > + TYPE_ALIGN (m)))) > > ...but how does looking at TYPE_ALIGN of the MAIN_VARIANT help with that > issue? I would hope that the MAIN_VARIANT hasn't had its TYPE_ALIGN > changed.
I thought the alignment of arrays could be increased from element type on some targets: unsigned align = TYPE_ALIGN (element); if (TYPE_USER_ALIGN (type)) align = MAX (align, TYPE_ALIGN (type)); else TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element); #ifdef ROUND_TYPE_ALIGN align = ROUND_TYPE_ALIGN (type, align, BITS_PER_UNIT); #else align = MAX (align, BITS_PER_UNIT); #endif SET_TYPE_ALIGN (type, align); But on a closer inspection, all targets which define ROUND_TYPE_ALIGN only bump alignment on structs/unions or vectors, never arrays, so for arrays it is just that MAX (align, BITS_PER_UNIT) on all targets and as C/C++ doesn't support arrays with bitfield elements (bet that part is there for Ada), indeed normally created ARRAY_TYPEs in C++ should have always TYPE_ALIGN equal to TYPE_ALIGN of the element type. 2025-08-14 Jakub Jelinek <ja...@redhat.com> PR c++/121524 * tree.cc (build_cplus_array_type): Don't reuse variant type if it has TREE_DEPRECATED or TREE_UNAVAILABLE flags set or, unless elt_type has TYPE_USER_ALIGN set and TYPE_ALIGN is TYPE_ALIGN of elt_type, TYPE_USER_ALIGN is not set. * g++.dg/cpp0x/gen-attrs-89.C: New test. --- gcc/cp/tree.cc.jj 2025-07-27 23:31:09.750006633 +0200 +++ gcc/cp/tree.cc 2025-08-13 17:17:17.248836248 +0200 @@ -1186,7 +1186,12 @@ build_cplus_array_type (tree elt_type, t for (t = m; t; t = TYPE_NEXT_VARIANT (t)) if (TREE_TYPE (t) == elt_type && TYPE_NAME (t) == NULL_TREE - && TYPE_ATTRIBUTES (t) == NULL_TREE) + && TYPE_ATTRIBUTES (t) == NULL_TREE + && (!TYPE_USER_ALIGN (t) + || (TYPE_USER_ALIGN (elt_type) + && TYPE_ALIGN (t) == TYPE_ALIGN (elt_type))) + && !TREE_DEPRECATED (t) + && !TREE_UNAVAILABLE (t)) break; if (!t) { --- gcc/testsuite/g++.dg/cpp0x/gen-attrs-89.C.jj 2025-08-13 15:49:54.956715791 +0200 +++ gcc/testsuite/g++.dg/cpp0x/gen-attrs-89.C 2025-08-13 15:49:29.933025752 +0200 @@ -0,0 +1,8 @@ +// PR c++/121524 +// { dg-do compile { target c++11 } } + +typedef unsigned int T; +struct A { unsigned a[8]; unsigned b; }; +struct B { T foo[8] [[gnu::aligned (32)]]; }; +struct C { T a[8]; T b; }; +static_assert (sizeof (C) == sizeof (A), ""); Jakub