https://gcc.gnu.org/g:1853b02d8c127740055242123db2d32cf9476ea9

commit r15-7822-g1853b02d8c127740055242123db2d32cf9476ea9
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Wed Mar 5 06:41:00 2025 +0100

    c++: Apply/diagnose attributes when instatiating 
ARRAY/POINTER/REFERENCE_TYPE [PR118787]
    
    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.
    
    2025-03-05  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.

Diff:
---
 gcc/cp/pt.cc                           | 24 +++++++++++++++++++-----
 gcc/testsuite/g++.dg/cpp0x/alignas22.C | 23 +++++++++++++++++++++++
 2 files changed, 42 insertions(+), 5 deletions(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 62d91a2dd159..c09a934580f2 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -16865,7 +16865,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, 
tree in_decl)
     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]
@@ -16935,9 +16937,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, 
tree in_decl)
             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);
@@ -16946,6 +16948,11 @@ tsubst (tree t, tree args, tsubst_flags_t complain, 
tree in_decl)
          /* 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:
@@ -17020,7 +17027,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, 
tree in_decl)
 
        /* 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.
@@ -17059,6 +17068,11 @@ tsubst (tree t, tree args, tsubst_flags_t complain, 
tree in_decl)
            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;
       }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/alignas22.C 
b/gcc/testsuite/g++.dg/cpp0x/alignas22.C
new file mode 100644
index 000000000000..e7929774c3c0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alignas22.C
@@ -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;
+}

Reply via email to