Hi! The following testcase IMO in violation of the P2552R3 paper doesn't pedwarn on alignas applying to dependent types or alignas with dependent argument.
tsubst was just ignoring TYPE_ATTRIBUTES. The following patch fixes it for the POINTER/REFERENCE_TYPE and ARRAY_TYPE cases, but perhaps we need to do the same also for other types (INTEGER_TYPE/REAL_TYPE and the like). I guess I'll need to construct more testcases. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 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