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

Reply via email to