2025-02-11 Jakub Jelinek <ja...@redhat.com>
PR c++/118787
* pt.cc (tsubst) <case ARRAY_TYPE>: Use return t; only if it doesn't
have any TYPE_ATTRIBUTES. Call apply_late_template_attributes.
<case POINTER_TYPE, case REFERENCE_TYPE>: Likewise. Formatting fix.
* g++.dg/cpp0x/alignas22.C: New test.
--- gcc/cp/pt.cc.jj 2025-02-07 17:03:13.560227281 +0100
+++ gcc/cp/pt.cc 2025-02-10 17:17:47.651313333 +0100
@@ -16854,7 +16854,9 @@ tsubst (tree t, tree args, tsubst_flags_
case POINTER_TYPE:
case REFERENCE_TYPE:
{
- if (type == TREE_TYPE (t) && TREE_CODE (type) != METHOD_TYPE)
+ if (type == TREE_TYPE (t)
+ && TREE_CODE (type) != METHOD_TYPE
+ && TYPE_ATTRIBUTES (t) == NULL_TREE)
return t;
/* [temp.deduct]
@@ -16924,9 +16926,9 @@ tsubst (tree t, tree args, tsubst_flags_
A,' while an attempt to create the type type rvalue reference to
cv T' creates the type T"
*/
- r = cp_build_reference_type
- (TREE_TYPE (type),
- TYPE_REF_IS_RVALUE (t) && TYPE_REF_IS_RVALUE (type));
+ r = cp_build_reference_type (TREE_TYPE (type),
+ TYPE_REF_IS_RVALUE (t)
+ && TYPE_REF_IS_RVALUE (type));
else
r = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t));
r = cp_build_qualified_type (r, cp_type_quals (t), complain);
@@ -16935,6 +16937,11 @@ tsubst (tree t, tree args, tsubst_flags_
/* Will this ever be needed for TYPE_..._TO values? */
layout_type (r);
+ if (!apply_late_template_attributes (&r, TYPE_ATTRIBUTES (t),
+ /*flags=*/0,
+ args, complain, in_decl))
+ return error_mark_node;
+
return r;
}
case OFFSET_TYPE:
@@ -17009,7 +17016,9 @@ tsubst (tree t, tree args, tsubst_flags_
/* As an optimization, we avoid regenerating the array type if
it will obviously be the same as T. */
- if (type == TREE_TYPE (t) && domain == TYPE_DOMAIN (t))
+ if (type == TREE_TYPE (t)
+ && domain == TYPE_DOMAIN (t)
+ && TYPE_ATTRIBUTES (t) == NULL_TREE)
return t;
/* These checks should match the ones in create_array_type_for_decl.
@@ -17048,6 +17057,11 @@ tsubst (tree t, tree args, tsubst_flags_
TYPE_USER_ALIGN (r) = 1;
}
+ if (!apply_late_template_attributes (&r, TYPE_ATTRIBUTES (t),
+ /*flags=*/0,
+ args, complain, in_decl))
+ return error_mark_node;
+
return r;
}
--- gcc/testsuite/g++.dg/cpp0x/alignas22.C.jj 2025-02-10 17:33:16.242452750 +0100
+++ gcc/testsuite/g++.dg/cpp0x/alignas22.C 2025-02-10 17:36:28.739046629
+0100
@@ -0,0 +1,23 @@
+// PR c++/118787
+// { dg-do compile { target c++11 } }
+// { dg-options "-pedantic" }
+
+template <typename T, int N>
+void foo (T & alignas (N)); // { dg-warning "'alignas' on a type
other than class" }
+template <typename T, int N>
+void bar (T (&)[N] alignas (N)); // { dg-warning "'alignas' on a type other than
class" }
+template <typename T, int N>
+using U = T * alignas (N); // { dg-warning "'alignas' on a type other
than class" }
+template <typename T, int N>
+using V = T[N] alignas (N); // { dg-warning "'alignas' on a type other
than class" }
+
+void
+baz ()
+{
+ int x alignas (4) = 0;
+ foo <int, 4> (x);
+ int y alignas (4) [4];
+ bar <int, 4> (y);
+ U <int, 4> u;
+ V <int, 4> v;
+}
Jakub