]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Apply/diagnose attributes when instatiating ARRAY/POINTER/REFERENCE_TYPE [PR118787]
authorJakub Jelinek <jakub@redhat.com>
Wed, 5 Mar 2025 05:41:00 +0000 (06:41 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 5 Mar 2025 05:41:00 +0000 (06:41 +0100)
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  <jakub@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
gcc/testsuite/g++.dg/cpp0x/alignas22.C [new file with mode: 0644]

index 62d91a2dd15982ece9a48c38fff174e31b1c6714..c09a934580f2c26891510bf933a5cb8979c366c6 100644 (file)
@@ -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 (file)
index 0000000..e792977
--- /dev/null
@@ -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;
+}