On 8/14/25 12:13 AM, Jakub Jelinek wrote:
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.
OK.
--- 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