https://gcc.gnu.org/g:801fb71f83624f0bf6d6bd27121d4a332103f7be

commit r15-7414-g801fb71f83624f0bf6d6bd27121d4a332103f7be
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Fri Feb 7 14:28:57 2025 +0100

    c++: Use cplus_decl_attributes rather than decl_attributes in grokdecl 
[PR118773]
    
    My r15-3046 change regressed the first half of the following testcase.
    When it calls decl_attributes, it doesn't handle attributes with
    dependent arguments correctly and so is now rejected that N is not
    a constant integer during template parsing.
    
    I've actually followed the pointer/reference case which did that
    too and that one has been failing for a couple of years on the
    second part of the testcase.
    
    Note, there is also
              if (decl_context != PARM && decl_context != TYPENAME)
                /* Assume that any attributes that get applied late to
                   templates will DTRT when applied to the declaration
                   as a whole.  */
                late_attrs = splice_template_attributes (&attrs, type);
              returned_attrs = decl_attributes (&type,
                                                attr_chainon (returned_attrs,
                                                              attrs),
                                                attr_flags);
              returned_attrs = attr_chainon (late_attrs, returned_attrs);
    call directly to decl_attributes in grokdeclarator, but this one handles
    the splicing manually, so maybe it is ok as is (and I don't have a testcase
    of anything misbehaving for that).
    
    2025-02-07  Jakub Jelinek  <ja...@redhat.com>
    
            PR c++/118773
            * decl.cc (grokdeclarator): Use cplus_decl_attributes rather than
            decl_attributes for std_attributes on pointer and array types.
    
            * g++.dg/cpp0x/gen-attrs-87.C: New test.
            * g++.dg/gomp/attrs-3.C: Adjust expected diagnostics.

Diff:
---
 gcc/cp/decl.cc                            |  5 ++---
 gcc/testsuite/g++.dg/cpp0x/gen-attrs-87.C | 10 ++++++++++
 gcc/testsuite/g++.dg/gomp/attrs-3.C       |  6 +++---
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 4238314558b1..84abc17ade0f 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -13846,7 +13846,7 @@ grokdeclarator (const cp_declarator *declarator,
 
               The optional attribute-specifier-seq appertains to the
               array type.  */
-           decl_attributes (&type, declarator->std_attributes, 0);
+           cplus_decl_attributes (&type, declarator->std_attributes, 0);
          break;
 
        case cdk_function:
@@ -14522,8 +14522,7 @@ grokdeclarator (const cp_declarator *declarator,
                 [the optional attribute-specifier-seq (7.6.1) appertains
                  to the pointer and not to the object pointed to].  */
          if (declarator->std_attributes)
-           decl_attributes (&type, declarator->std_attributes,
-                            0);
+           cplus_decl_attributes (&type, declarator->std_attributes, 0);
 
          ctype = NULL_TREE;
          break;
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-87.C 
b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-87.C
new file mode 100644
index 000000000000..465e80921453
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-87.C
@@ -0,0 +1,10 @@
+// PR c++/118773
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+template <unsigned N>
+using T = char[4] [[gnu::aligned (N)]];
+T<2> t;
+template <unsigned N>
+using U = char *[[gnu::aligned (N)]]*;
+U<__alignof (char *)> u;
diff --git a/gcc/testsuite/g++.dg/gomp/attrs-3.C 
b/gcc/testsuite/g++.dg/gomp/attrs-3.C
index 5658b3a86895..d2dddfa33525 100644
--- a/gcc/testsuite/g++.dg/gomp/attrs-3.C
+++ b/gcc/testsuite/g++.dg/gomp/attrs-3.C
@@ -32,10 +32,10 @@ foo ()
     i++;
   auto a = [] () [[omp::directive (threadprivate (t1))]] {};   // { dg-error 
"'omp::directive' not allowed to be specified in this context" }
   int [[omp::directive (threadprivate (t2))]] b;               // { dg-warning 
"attribute ignored" }
-  int *[[omp::directive (threadprivate (t3))]] c;              // { dg-warning 
"'omp::directive' scoped attribute directive ignored" }
-  int &[[omp::directive (threadprivate (t4))]] d = b;          // { dg-warning 
"'omp::directive' scoped attribute directive ignored" }
+  int *[[omp::directive (threadprivate (t3))]] c;              // { dg-error 
"'omp::directive' not allowed to be specified in this context" }
+  int &[[omp::directive (threadprivate (t4))]] d = b;          // { dg-error 
"'omp::directive' not allowed to be specified in this context" }
   typedef int T [[omp::directive (threadprivate (t5))]];       // { dg-error 
"'omp::directive' not allowed to be specified in this context" }
   int e [[omp::directive (threadprivate (t6))]] [10];          // { dg-error 
"'omp::directive' not allowed to be specified in this context" }
-  int f[10] [[omp::directive (threadprivate (t6))]];           // { dg-warning 
"'omp::directive' scoped attribute directive ignored" }
+  int f[10] [[omp::directive (threadprivate (t6))]];           // { dg-error 
"'omp::directive' not allowed to be specified in this context" }
   struct [[omp::directive (threadprivate (t7))]] S {};         // { dg-error 
"'omp::directive' not allowed to be specified in this context" }
 }

Reply via email to