https://github.com/elizabethandrews updated 
https://github.com/llvm/llvm-project/pull/227421

>From e3784e1ab611390c17c6fd628b79f8b5900e601b Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <[email protected]>
Date: Tue, 29 Sep 2026 11:00:58 -0700
Subject: [PATCH 1/2] [clang] Centralize common checks for type attributes

Type attributes were not run through the common attribute feature
checks in checkCommonAttributeFeatures(). As a result, the constraints
declared for a type attribute in Attr.td, such as LangOpts gating.
were not honored unless each attribute handler did it themselves.

This PR centralizes the checks and removes the now-redundant
per-handler checks.

Fixes : https://github.com/llvm/llvm-project/issues/225581

AI Use - I used claude to find redundant checks in handlers and
modify tests.
---
 clang/include/clang/Sema/Sema.h               |  2 +
 clang/lib/Sema/SemaAttr.cpp                   | 41 ++++++++-----
 clang/lib/Sema/SemaType.cpp                   | 59 ++-----------------
 clang/test/Sema/attr-btf_tag.c                |  4 +-
 clang/test/Sema/attr-function-return.c        |  2 +-
 clang/test/Sema/ext_vector_casts.c            |  3 +
 .../test/SemaCXX/attr-unsafe-buffer-usage.cpp |  3 +-
 clang/test/SemaCXX/matrix-type.cpp            |  3 +
 clang/test/SemaObjC/attr-objc-gc.m            |  2 +-
 .../sycl-address-space-attr-on-non-sycl.cpp   | 21 +++++++
 10 files changed, 67 insertions(+), 73 deletions(-)
 create mode 100644 clang/test/SemaSYCL/sycl-address-space-attr-on-non-sycl.cpp

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index eb3b908351448d..70cc92a06e271a 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2447,6 +2447,8 @@ class Sema final : public SemaBase {
                                     bool SkipArgCountCheck = false);
   bool checkCommonAttributeFeatures(const Stmt *S, const ParsedAttr &A,
                                     bool SkipArgCountCheck = false);
+  bool checkCommonAttributeFeatures(const ParsedAttr &A,
+                                    bool SkipArgCountCheck = false);
 
   ///@}
 
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index 35d14a4444595a..9b995059048c76 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -1620,28 +1620,16 @@ void Sema::PopPragmaVisibility(bool IsNamespaceEnd, 
SourceLocation EndLoc) {
     FreeVisContext();
 }
 
-template <typename Ty>
-static bool checkCommonAttributeFeatures(Sema &S, const Ty *Node,
-                                         const ParsedAttr &A,
+static bool checkCommonAttributeFeatures(Sema &S, const ParsedAttr &A,
                                          bool SkipArgCountCheck) {
-  // Several attributes carry different semantics than the parsing requires, so
-  // those are opted out of the common argument checks.
-  //
-  // We also bail on unknown and ignored attributes because those are handled
-  // as part of the target-specific handling logic.
+  // We bail on unknown and ignored attributes because those are handled as
+  // part of the target-specific handling logic.
   if (A.getKind() == ParsedAttr::UnknownAttribute)
     return false;
   // Check whether the attribute requires specific language extensions to be
   // enabled.
   if (!A.diagnoseLangOpts(S))
     return true;
-  // Check whether the attribute appertains to the given subject.
-  if (!A.diagnoseAppertainsTo(S, Node))
-    return true;
-  // Check whether the attribute is mutually exclusive with other attributes
-  // that have already been applied to the declaration.
-  if (!A.diagnoseMutualExclusion(S, Node))
-    return true;
   // Check whether the attribute exists in the target architecture.
   if (S.CheckAttrTarget(A))
     return true;
@@ -1668,6 +1656,25 @@ static bool checkCommonAttributeFeatures(Sema &S, const 
Ty *Node,
   return false;
 }
 
+template <typename Ty>
+static bool checkCommonAttributeFeatures(Sema &S, const Ty *Node,
+                                         const ParsedAttr &A,
+                                         bool SkipArgCountCheck) {
+  // Run the checks shared with type attributes (language options, target, and
+  // argument count). This also bails on unknown and ignored attributes.
+  if (checkCommonAttributeFeatures(S, A, SkipArgCountCheck))
+    return true;
+  // Check whether the attribute appertains to the given subject.
+  if (!A.diagnoseAppertainsTo(S, Node))
+    return true;
+  // Check whether the attribute is mutually exclusive with other attributes
+  // that have already been applied to the declaration.
+  if (!A.diagnoseMutualExclusion(S, Node))
+    return true;
+
+  return false;
+}
+
 bool Sema::checkCommonAttributeFeatures(const Decl *D, const ParsedAttr &A,
                                         bool SkipArgCountCheck) {
   return ::checkCommonAttributeFeatures(*this, D, A, SkipArgCountCheck);
@@ -1676,3 +1683,7 @@ bool Sema::checkCommonAttributeFeatures(const Stmt *S, 
const ParsedAttr &A,
                                         bool SkipArgCountCheck) {
   return ::checkCommonAttributeFeatures(*this, S, A, SkipArgCountCheck);
 }
+bool Sema::checkCommonAttributeFeatures(const ParsedAttr &A,
+                                        bool SkipArgCountCheck) {
+  return ::checkCommonAttributeFeatures(*this, A, SkipArgCountCheck);
+}
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 2796ac2929f460..b6ccc52504e4fb 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6607,23 +6607,6 @@ static void HandleBTFTypeTagAttribute(QualType &Type, 
const ParsedAttr &Attr,
                                       TypeProcessingState &State) {
   Sema &S = State.getSema();
 
-  // This attribute is only supported in C.
-  // FIXME: we should implement checkCommonAttributeFeatures() in SemaAttr.cpp
-  // such that it handles type attributes, and then call that from
-  // processTypeAttrs() instead of one-off checks like this.
-  if (!Attr.diagnoseLangOpts(S)) {
-    Attr.setInvalid();
-    return;
-  }
-
-  // Check the number of attribute arguments.
-  if (Attr.getNumArgs() != 1) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-        << Attr << 1;
-    Attr.setInvalid();
-    return;
-  }
-
   // Ensure the argument is a string.
   auto *StrLiteral = dyn_cast<StringLiteral>(Attr.getArgAsExpr(0));
   if (!StrLiteral) {
@@ -8531,13 +8514,6 @@ static void HandleVectorSizeAttr(QualType &CurType, 
const ParsedAttr &Attr,
 /// a type.
 static void HandleExtVectorTypeAttr(QualType &CurType, const ParsedAttr &Attr,
                                     Sema &S) {
-  // check the attribute arguments.
-  if (Attr.getNumArgs() != 1) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << Attr
-                                                                      << 1;
-    return;
-  }
-
   Expr *SizeExpr = Attr.getArgAsExpr(0);
   QualType T = S.BuildExtVectorType(CurType, SizeExpr, Attr.getLoc());
   if (!T.isNull())
@@ -8639,13 +8615,6 @@ static void HandleNeonVectorTypeAttr(QualType &CurType, 
const ParsedAttr &Attr,
     return;
   }
 
-  // Check the attribute arguments.
-  if (Attr.getNumArgs() != 1) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-        << Attr << 1;
-    Attr.setInvalid();
-    return;
-  }
   // The number of elements must be an ICE.
   llvm::APSInt numEltsInt(32);
   if (!verifyValidIntegerConstantExpr(S, Attr, numEltsInt))
@@ -8752,14 +8721,6 @@ static void HandleArmSveVectorBitsTypeAttr(QualType 
&CurType, ParsedAttr &Attr,
     return;
   }
 
-  // Check the attribute arguments.
-  if (Attr.getNumArgs() != 1) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-        << Attr << 1;
-    Attr.setInvalid();
-    return;
-  }
-
   // The vector size must be an integer constant expression.
   llvm::APSInt SveVectorSizeInBits(32);
   if (!verifyValidIntegerConstantExpr(S, Attr, SveVectorSizeInBits))
@@ -8836,14 +8797,6 @@ static void HandleRISCVRVVVectorBitsTypeAttr(QualType 
&CurType,
     return;
   }
 
-  // Check the attribute arguments.
-  if (Attr.getNumArgs() != 1) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-        << Attr << 1;
-    Attr.setInvalid();
-    return;
-  }
-
   // The vector size must be an integer constant expression.
   llvm::APSInt RVVVectorSizeInBits(32);
   if (!verifyValidIntegerConstantExpr(S, Attr, RVVVectorSizeInBits))
@@ -8965,12 +8918,6 @@ static void HandleMatrixTypeAttr(QualType &CurType, 
const ParsedAttr &Attr,
     return;
   }
 
-  if (Attr.getNumArgs() != 2) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
-        << Attr << 2;
-    return;
-  }
-
   Expr *RowsExpr = Attr.getArgAsExpr(0);
   Expr *ColsExpr = Attr.getArgAsExpr(1);
   QualType T = S.BuildMatrixType(CurType, RowsExpr, ColsExpr, Attr.getLoc());
@@ -9096,6 +9043,12 @@ static void processTypeAttrs(TypeProcessingState &state, 
QualType &type,
       }
     }
 
+    if (attr.isTypeAttr() &&
+        state.getSema().checkCommonAttributeFeatures(attr)) {
+      attr.setInvalid();
+      continue;
+    }
+
     // If this is an attribute we can handle, do so now,
     // otherwise, add it to the FnAttrs list for rechaining.
     switch (attr.getKind()) {
diff --git a/clang/test/Sema/attr-btf_tag.c b/clang/test/Sema/attr-btf_tag.c
index cbb21a5a88bb68..e58420e0dd2772 100644
--- a/clang/test/Sema/attr-btf_tag.c
+++ b/clang/test/Sema/attr-btf_tag.c
@@ -29,11 +29,11 @@ enum e1 {
 
 enum e2 {
   E2
-} __tag_no_arg; // expected-error {{'btf_decl_tag' attribute only applies to 
variables, functions, structs, unions, classes, non-static data members, and 
typedefs}}
+} __tag_no_arg; // expected-error {{'btf_decl_tag' attribute takes one 
argument}}
 
 enum e3 {
   E3
-} __tag_2_arg; // expected-error {{'btf_decl_tag' attribute only applies to 
variables, functions, structs, unions, classes, non-static data members, and 
typedefs}}
+} __tag_2_arg; // expected-error {{'btf_decl_tag' attribute takes one 
argument}}
 
 int __tag1 __tag2 foo(struct t1 *arg, struct t2 *arg2);
 int __tag2 __tag3 foo(struct t1 *arg, struct t2 *arg2);
diff --git a/clang/test/Sema/attr-function-return.c 
b/clang/test/Sema/attr-function-return.c
index d2c9156da7ab61..be72a9916e9c68 100644
--- a/clang/test/Sema/attr-function-return.c
+++ b/clang/test/Sema/attr-function-return.c
@@ -20,4 +20,4 @@ __attribute__((function_return(5))) void a(void) {}
 __attribute__((function_return)) void b(void) {}
 
 // expected-warning@+1 {{'function_return' attribute only applies to 
functions}}
-__attribute__((function_return)) int c;
+__attribute__((function_return("keep"))) int c;
diff --git a/clang/test/Sema/ext_vector_casts.c 
b/clang/test/Sema/ext_vector_casts.c
index 8bf2737e0bfab1..cdc482d548c724 100644
--- a/clang/test/Sema/ext_vector_casts.c
+++ b/clang/test/Sema/ext_vector_casts.c
@@ -127,3 +127,6 @@ static void splats(int i, long l, __uint128_t t, float f, 
double d) {
   vd = l + vd; // expected-warning {{implicit conversion from 'long' to 
'double2' (vector of 2 'double' values) may lose precision}}
   vd = vd + t; // expected-warning {{implicit conversion from '__uint128_t' 
(aka 'unsigned __int128') to 'double2' (vector of 2 'double' values) may lose 
precision}}
 }
+
+typedef int no_arg __attribute__((ext_vector_type()));      // expected-error 
{{'ext_vector_type' attribute takes one argument}}
+typedef int two_args __attribute__((ext_vector_type(2, 4))); // expected-error 
{{'ext_vector_type' attribute takes one argument}}
diff --git a/clang/test/SemaCXX/attr-unsafe-buffer-usage.cpp 
b/clang/test/SemaCXX/attr-unsafe-buffer-usage.cpp
index cab67784d90756..fcadd706c4b403 100644
--- a/clang/test/SemaCXX/attr-unsafe-buffer-usage.cpp
+++ b/clang/test/SemaCXX/attr-unsafe-buffer-usage.cpp
@@ -3,4 +3,5 @@
 // Function annotations.
 [[clang::unsafe_buffer_usage]]
 void f(int *buf, int size);
-void g(int *buffer [[clang::unsafe_buffer_usage("buffer")]], int size); // 
expected-warning {{'clang::unsafe_buffer_usage' attribute only applies to 
functions}}
+void g(int *buffer [[clang::unsafe_buffer_usage]], int size); // 
expected-warning {{'clang::unsafe_buffer_usage' attribute only applies to 
functions}}
+void h(int *buffer [[clang::unsafe_buffer_usage("buffer")]], int size); // 
expected-error {{'clang::unsafe_buffer_usage' attribute takes no arguments}}
diff --git a/clang/test/SemaCXX/matrix-type.cpp 
b/clang/test/SemaCXX/matrix-type.cpp
index 3b3b22dea741ad..fc2d88f04073d6 100644
--- a/clang/test/SemaCXX/matrix-type.cpp
+++ b/clang/test/SemaCXX/matrix-type.cpp
@@ -15,6 +15,9 @@ void matrix_var_dimensions(int Rows, unsigned Columns, char 
C) {
   using matrix7_t = int __attribute__((matrix_type(char, 0)));    // 
expected-error{{expected '(' for function-style cast or type construction}}
   using matrix8_t = int __attribute__((matrix_type(1048576, 1))); // 
expected-error{{matrix row size too large}}
   using matrix8_t = int __attribute__((matrix_type(1048576, 1048576))); // 
expected-error{{matrix row and column size too large}}
+  using matrix9_t = int __attribute__((matrix_type()));           // 
expected-error{{'matrix_type' attribute requires exactly 2 arguments}}
+  using matrix10_t = int __attribute__((matrix_type(1)));         // 
expected-error{{'matrix_type' attribute requires exactly 2 arguments}}
+  using matrix11_t = int __attribute__((matrix_type(1, 2, 3)));   // 
expected-error{{'matrix_type' attribute requires exactly 2 arguments}}
 }
 
 struct S1 {};
diff --git a/clang/test/SemaObjC/attr-objc-gc.m 
b/clang/test/SemaObjC/attr-objc-gc.m
index c199df725cd9fa..88d76e73166750 100644
--- a/clang/test/SemaObjC/attr-objc-gc.m
+++ b/clang/test/SemaObjC/attr-objc-gc.m
@@ -2,7 +2,7 @@
 static id __attribute((objc_gc(weak))) a;
 static id __attribute((objc_gc(strong))) b;
 
-static id __attribute((objc_gc())) c; // expected-error{{'objc_gc' attribute 
requires a string}}
+static id __attribute((objc_gc())) c; // expected-error{{'objc_gc' attribute 
takes one argument}}
 static id __attribute((objc_gc(123))) d; // expected-error{{'objc_gc' 
attribute requires a string}}
 static id __attribute((objc_gc(foo, 456))) e; // expected-error{{'objc_gc' 
attribute takes one argument}}
 static id __attribute((objc_gc(hello))) f; // expected-warning{{'objc_gc' 
attribute argument not supported: 'hello'}}
diff --git a/clang/test/SemaSYCL/sycl-address-space-attr-on-non-sycl.cpp 
b/clang/test/SemaSYCL/sycl-address-space-attr-on-non-sycl.cpp
new file mode 100644
index 00000000000000..583bea7ac5c36d
--- /dev/null
+++ b/clang/test/SemaSYCL/sycl-address-space-attr-on-non-sycl.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -fsycl-is-device -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fsycl-is-host -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -x c++ %s
+
+// The SYCL address space attributes are only enabled in SYCL compilations.
+
+#ifndef SYCL_LANGUAGE_VERSION
+// expected-warning@#global   {{'clang::sycl_global' attribute ignored}}
+// expected-warning@#local    {{'clang::sycl_local' attribute ignored}}
+// expected-warning@#private  {{'clang::sycl_private' attribute ignored}}
+// expected-warning@#generic  {{'clang::sycl_generic' attribute ignored}}
+// expected-warning@#constant {{'clang::sycl_constant' attribute ignored}}
+#else
+// expected-no-diagnostics
+#endif
+
+using global_ptr = int [[clang::sycl_global]] *;     // #global
+using local_ptr = int [[clang::sycl_local]] *;       // #local
+using private_ptr = int [[clang::sycl_private]] *;   // #private
+using generic_ptr = int [[clang::sycl_generic]] *;   // #generic
+using constant_ptr = int [[clang::sycl_constant]] *; // #constant

>From 6570405a15d092e6b3a5ad691da3502bfc9b31b7 Mon Sep 17 00:00:00 2001
From: Elizabeth Andrews <[email protected]>
Date: Mon, 5 Oct 2026 12:05:28 -0700
Subject: [PATCH 2/2] Apply review comments

---
 clang/include/clang/Sema/ParsedAttr.h         |  8 ++++
 clang/include/clang/Sema/Sema.h               |  2 +-
 clang/lib/Sema/SemaAttr.cpp                   | 45 +++++++++----------
 clang/lib/Sema/SemaType.cpp                   |  2 +-
 clang/test/Sema/attr-btf_tag.c                |  4 +-
 clang/test/Sema/attr-function-return.c        |  2 +-
 .../test/SemaCXX/attr-unsafe-buffer-usage.cpp |  3 +-
 .../sycl-address-space-attr-ignored.cpp       | 21 +++++++++
 .../sycl-address-space-attr-on-non-sycl.cpp   | 21 ---------
 9 files changed, 56 insertions(+), 52 deletions(-)
 create mode 100644 clang/test/SemaSYCL/sycl-address-space-attr-ignored.cpp
 delete mode 100644 clang/test/SemaSYCL/sycl-address-space-attr-on-non-sycl.cpp

diff --git a/clang/include/clang/Sema/ParsedAttr.h 
b/clang/include/clang/Sema/ParsedAttr.h
index a606d66ef34c32..568fb0420d1ed7 100644
--- a/clang/include/clang/Sema/ParsedAttr.h
+++ b/clang/include/clang/Sema/ParsedAttr.h
@@ -518,6 +518,10 @@ class ParsedAttr final
   void handleAttrWithDelayedArgs(Sema &S, Decl *D) const;
   bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
   bool diagnoseAppertainsTo(class Sema &S, const Stmt *St) const;
+  // This function stub exists for parity with the declaration and statement
+  // checking code so that checkCommonAttributeFeatures() can work generically
+  // on types.
+  bool diagnoseAppertainsTo(class Sema &S, QualType T) const { return true; }
   bool diagnoseMutualExclusion(class Sema &S, const Decl *D) const;
   // This function stub exists for parity with the declaration checking code so
   // that checkCommonAttributeFeatures() can work generically on declarations
@@ -525,6 +529,10 @@ class ParsedAttr final
   bool diagnoseMutualExclusion(class Sema &S, const Stmt *St) const {
     return true;
   }
+  // This function stub exists for parity with the declaration and statement
+  // checking code so that checkCommonAttributeFeatures() can work generically
+  // on types.
+  bool diagnoseMutualExclusion(class Sema &S, QualType T) const { return true; 
}
   bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const;
   void getMatchRules(const LangOptions &LangOpts,
                      SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>>
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 70cc92a06e271a..36e6d1e319e478 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2447,7 +2447,7 @@ class Sema final : public SemaBase {
                                     bool SkipArgCountCheck = false);
   bool checkCommonAttributeFeatures(const Stmt *S, const ParsedAttr &A,
                                     bool SkipArgCountCheck = false);
-  bool checkCommonAttributeFeatures(const ParsedAttr &A,
+  bool checkCommonAttributeFeatures(QualType T, const ParsedAttr &A,
                                     bool SkipArgCountCheck = false);
 
   ///@}
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index 9b995059048c76..a25e9b591860b4 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -1620,16 +1620,32 @@ void Sema::PopPragmaVisibility(bool IsNamespaceEnd, 
SourceLocation EndLoc) {
     FreeVisContext();
 }
 
-static bool checkCommonAttributeFeatures(Sema &S, const ParsedAttr &A,
+// 'Subject' is the entity the attribute appertains to: a Decl, a Stmt, or a
+// QualType. Attr.td subject lists currently only accept declarations and
+// statements, so the appertainment and mutual exclusion checks for a QualType
+// are stubs that always succeed.
+template <typename SubjectTy>
+static bool checkCommonAttributeFeatures(Sema &S, SubjectTy Subject,
+                                         const ParsedAttr &A,
                                          bool SkipArgCountCheck) {
-  // We bail on unknown and ignored attributes because those are handled as
-  // part of the target-specific handling logic.
+  // Several attributes carry different semantics than the parsing requires, so
+  // those are opted out of the common argument checks.
+  //
+  // We also bail on unknown and ignored attributes because those are handled
+  // as part of the target-specific handling logic.
   if (A.getKind() == ParsedAttr::UnknownAttribute)
     return false;
   // Check whether the attribute requires specific language extensions to be
   // enabled.
   if (!A.diagnoseLangOpts(S))
     return true;
+  // Check whether the attribute appertains to the given subject.
+  if (!A.diagnoseAppertainsTo(S, Subject))
+    return true;
+  // Check whether the attribute is mutually exclusive with other attributes
+  // that have already been applied to the declaration.
+  if (!A.diagnoseMutualExclusion(S, Subject))
+    return true;
   // Check whether the attribute exists in the target architecture.
   if (S.CheckAttrTarget(A))
     return true;
@@ -1656,25 +1672,6 @@ static bool checkCommonAttributeFeatures(Sema &S, const 
ParsedAttr &A,
   return false;
 }
 
-template <typename Ty>
-static bool checkCommonAttributeFeatures(Sema &S, const Ty *Node,
-                                         const ParsedAttr &A,
-                                         bool SkipArgCountCheck) {
-  // Run the checks shared with type attributes (language options, target, and
-  // argument count). This also bails on unknown and ignored attributes.
-  if (checkCommonAttributeFeatures(S, A, SkipArgCountCheck))
-    return true;
-  // Check whether the attribute appertains to the given subject.
-  if (!A.diagnoseAppertainsTo(S, Node))
-    return true;
-  // Check whether the attribute is mutually exclusive with other attributes
-  // that have already been applied to the declaration.
-  if (!A.diagnoseMutualExclusion(S, Node))
-    return true;
-
-  return false;
-}
-
 bool Sema::checkCommonAttributeFeatures(const Decl *D, const ParsedAttr &A,
                                         bool SkipArgCountCheck) {
   return ::checkCommonAttributeFeatures(*this, D, A, SkipArgCountCheck);
@@ -1683,7 +1680,7 @@ bool Sema::checkCommonAttributeFeatures(const Stmt *S, 
const ParsedAttr &A,
                                         bool SkipArgCountCheck) {
   return ::checkCommonAttributeFeatures(*this, S, A, SkipArgCountCheck);
 }
-bool Sema::checkCommonAttributeFeatures(const ParsedAttr &A,
+bool Sema::checkCommonAttributeFeatures(QualType T, const ParsedAttr &A,
                                         bool SkipArgCountCheck) {
-  return ::checkCommonAttributeFeatures(*this, A, SkipArgCountCheck);
+  return ::checkCommonAttributeFeatures(*this, T, A, SkipArgCountCheck);
 }
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index b6ccc52504e4fb..88f8bf6a5bcbec 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -9044,7 +9044,7 @@ static void processTypeAttrs(TypeProcessingState &state, 
QualType &type,
     }
 
     if (attr.isTypeAttr() &&
-        state.getSema().checkCommonAttributeFeatures(attr)) {
+        state.getSema().checkCommonAttributeFeatures(type, attr)) {
       attr.setInvalid();
       continue;
     }
diff --git a/clang/test/Sema/attr-btf_tag.c b/clang/test/Sema/attr-btf_tag.c
index e58420e0dd2772..cbb21a5a88bb68 100644
--- a/clang/test/Sema/attr-btf_tag.c
+++ b/clang/test/Sema/attr-btf_tag.c
@@ -29,11 +29,11 @@ enum e1 {
 
 enum e2 {
   E2
-} __tag_no_arg; // expected-error {{'btf_decl_tag' attribute takes one 
argument}}
+} __tag_no_arg; // expected-error {{'btf_decl_tag' attribute only applies to 
variables, functions, structs, unions, classes, non-static data members, and 
typedefs}}
 
 enum e3 {
   E3
-} __tag_2_arg; // expected-error {{'btf_decl_tag' attribute takes one 
argument}}
+} __tag_2_arg; // expected-error {{'btf_decl_tag' attribute only applies to 
variables, functions, structs, unions, classes, non-static data members, and 
typedefs}}
 
 int __tag1 __tag2 foo(struct t1 *arg, struct t2 *arg2);
 int __tag2 __tag3 foo(struct t1 *arg, struct t2 *arg2);
diff --git a/clang/test/Sema/attr-function-return.c 
b/clang/test/Sema/attr-function-return.c
index be72a9916e9c68..d2c9156da7ab61 100644
--- a/clang/test/Sema/attr-function-return.c
+++ b/clang/test/Sema/attr-function-return.c
@@ -20,4 +20,4 @@ __attribute__((function_return(5))) void a(void) {}
 __attribute__((function_return)) void b(void) {}
 
 // expected-warning@+1 {{'function_return' attribute only applies to 
functions}}
-__attribute__((function_return("keep"))) int c;
+__attribute__((function_return)) int c;
diff --git a/clang/test/SemaCXX/attr-unsafe-buffer-usage.cpp 
b/clang/test/SemaCXX/attr-unsafe-buffer-usage.cpp
index fcadd706c4b403..cab67784d90756 100644
--- a/clang/test/SemaCXX/attr-unsafe-buffer-usage.cpp
+++ b/clang/test/SemaCXX/attr-unsafe-buffer-usage.cpp
@@ -3,5 +3,4 @@
 // Function annotations.
 [[clang::unsafe_buffer_usage]]
 void f(int *buf, int size);
-void g(int *buffer [[clang::unsafe_buffer_usage]], int size); // 
expected-warning {{'clang::unsafe_buffer_usage' attribute only applies to 
functions}}
-void h(int *buffer [[clang::unsafe_buffer_usage("buffer")]], int size); // 
expected-error {{'clang::unsafe_buffer_usage' attribute takes no arguments}}
+void g(int *buffer [[clang::unsafe_buffer_usage("buffer")]], int size); // 
expected-warning {{'clang::unsafe_buffer_usage' attribute only applies to 
functions}}
diff --git a/clang/test/SemaSYCL/sycl-address-space-attr-ignored.cpp 
b/clang/test/SemaSYCL/sycl-address-space-attr-ignored.cpp
new file mode 100644
index 00000000000000..4857aaf000d9af
--- /dev/null
+++ b/clang/test/SemaSYCL/sycl-address-space-attr-ignored.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -x c++ %s
+// RUN: %clang_cc1 -fsyntax-only -verify -x clcpp %s
+// RUN: %clang_cc1 -fsyntax-only -verify -x cuda %s
+// RUN: %clang_cc1 -fsyntax-only -verify -x hip %s
+
+// The SYCL address space attributes are only enabled in SYCL compilations.
+
+// expected-warning@+1 {{'clang::sycl_global' attribute ignored}}
+using global_ptr = int [[clang::sycl_global]] *;
+
+// expected-warning@+1 {{'clang::sycl_local' attribute ignored}}
+using local_ptr = int [[clang::sycl_local]] *;
+
+// expected-warning@+1 {{'clang::sycl_private' attribute ignored}}
+using private_ptr = int [[clang::sycl_private]] *;
+
+// expected-warning@+1 {{'clang::sycl_generic' attribute ignored}}
+using generic_ptr = int [[clang::sycl_generic]] *;
+
+// expected-warning@+1 {{'clang::sycl_constant' attribute ignored}}
+using constant_ptr = int [[clang::sycl_constant]] *;
diff --git a/clang/test/SemaSYCL/sycl-address-space-attr-on-non-sycl.cpp 
b/clang/test/SemaSYCL/sycl-address-space-attr-on-non-sycl.cpp
deleted file mode 100644
index 583bea7ac5c36d..00000000000000
--- a/clang/test/SemaSYCL/sycl-address-space-attr-on-non-sycl.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -fsycl-is-device -verify %s
-// RUN: %clang_cc1 -fsyntax-only -fsycl-is-host -verify %s
-// RUN: %clang_cc1 -fsyntax-only -verify -x c++ %s
-
-// The SYCL address space attributes are only enabled in SYCL compilations.
-
-#ifndef SYCL_LANGUAGE_VERSION
-// expected-warning@#global   {{'clang::sycl_global' attribute ignored}}
-// expected-warning@#local    {{'clang::sycl_local' attribute ignored}}
-// expected-warning@#private  {{'clang::sycl_private' attribute ignored}}
-// expected-warning@#generic  {{'clang::sycl_generic' attribute ignored}}
-// expected-warning@#constant {{'clang::sycl_constant' attribute ignored}}
-#else
-// expected-no-diagnostics
-#endif
-
-using global_ptr = int [[clang::sycl_global]] *;     // #global
-using local_ptr = int [[clang::sycl_local]] *;       // #local
-using private_ptr = int [[clang::sycl_private]] *;   // #private
-using generic_ptr = int [[clang::sycl_generic]] *;   // #generic
-using constant_ptr = int [[clang::sycl_constant]] *; // #constant

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to