[clang] [AArch64][SME] Add diagnostics for SME attributes on lambda functions (PR #121777)

Kerry McLaughlin via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 8 09:36:09 PST 2025


https://github.com/kmclaughlin-arm updated https://github.com/llvm/llvm-project/pull/121777

>From 00772b871de43a5e30aca2a65a89675117cafbf1 Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Tue, 31 Dec 2024 17:22:02 +0000
Subject: [PATCH 1/4] [AArch64][SME] Add diagnostics to
 CheckConstexprFunctionDefinition

CheckFunctionDeclaration emits diagnostics if any SME attributes are used
by a function definition without the required +sme or +sme2 target features.
This patch adds similar diagnostics to CheckConstexprFunctionDefinition to
ensure this emits the same errors when attributes such as __arm_new("za")
are found without +sme/+sme2.
---
 clang/lib/Sema/SemaDeclCXX.cpp                | 22 +++++++++++++++++++
 ...-sme-func-attrs-without-target-feature.cpp |  8 ++++++-
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index c5a72cf812ebc9..3ee26ebabcfdd5 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -1854,6 +1854,28 @@ bool Sema::CheckConstexprFunctionDefinition(const FunctionDecl *NewFD,
     }
   }
 
+  if (Context.getTargetInfo().getTriple().isAArch64()) {
+    const auto *Attr = NewFD->getAttr<ArmNewAttr>();
+    bool LocallyStreaming = NewFD->hasAttr<ArmLocallyStreamingAttr>();
+    llvm::StringMap<bool> FeatureMap;
+    Context.getFunctionFeatureMap(FeatureMap, NewFD);
+    if (!FeatureMap.contains("sme") && LocallyStreaming) {
+      Diag(NewFD->getLocation(),
+           diag::err_sme_definition_using_sm_in_non_sme_target);
+      return false;
+    }
+    if (Attr && Attr->isNewZA() && !FeatureMap.contains("sme")) {
+      Diag(NewFD->getLocation(),
+           diag::err_sme_definition_using_za_in_non_sme_target);
+      return false;
+    }
+    if (Attr && Attr->isNewZT0() && !FeatureMap.contains("sme2")) {
+      Diag(NewFD->getLocation(),
+           diag::err_sme_definition_using_zt0_in_non_sme2_target);
+      return false;
+    }
+  }
+
   // - each of its parameter types shall be a literal type; (removed in C++23)
   if (!getLangOpts().CPlusPlus23 &&
       !CheckConstexprParameterTypes(*this, NewFD, Kind))
diff --git a/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp b/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
index ec6bb6f5035784..a046b5aa1325cc 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
+++ b/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -std=c++23 -fsyntax-only -verify %s
 
 // This test is testing the diagnostics that Clang emits when compiling without '+sme'.
 
@@ -48,3 +48,9 @@ void streaming_compatible_def2(void (*streaming_fn_ptr)(void) __arm_streaming,
 // Also test when call-site is not a function.
 int streaming_decl_ret_int() __arm_streaming;
 int x = streaming_decl_ret_int(); // expected-error {{call to a streaming function requires 'sme'}}
+
+void sme_attrs_method_decls() {
+  [&] __arm_locally_streaming () { return; }();  // expected-error {{function executed in streaming-SVE mode requires 'sme'}}
+  [&] __arm_new("za") () { return; }();  // expected-error {{function using ZA state requires 'sme'}}
+  [&] __arm_new("zt0") () { return; }();  // expected-error {{function using ZT0 state requires 'sme2'}}
+}

>From bbc80c21e66958a149cdfcf37a56ea5825728a2d Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Mon, 6 Jan 2025 15:55:36 +0000
Subject: [PATCH 2/4] - Move diagnostics to SemaARM.cpp

---
 clang/include/clang/Sema/SemaARM.h            |  1 +
 clang/lib/Sema/SemaARM.cpp                    | 53 ++++++++++++++++++
 clang/lib/Sema/SemaDecl.cpp                   | 55 +------------------
 clang/lib/Sema/SemaDeclCXX.cpp                | 24 +-------
 ...-sme-func-attrs-without-target-feature.cpp |  2 +-
 5 files changed, 61 insertions(+), 74 deletions(-)

diff --git a/clang/include/clang/Sema/SemaARM.h b/clang/include/clang/Sema/SemaARM.h
index 8c4c56e2221301..08b03af7fd4bc6 100644
--- a/clang/include/clang/Sema/SemaARM.h
+++ b/clang/include/clang/Sema/SemaARM.h
@@ -79,6 +79,7 @@ class SemaARM : public SemaBase {
   void handleNewAttr(Decl *D, const ParsedAttr &AL);
   void handleCmseNSEntryAttr(Decl *D, const ParsedAttr &AL);
   void handleInterruptAttr(Decl *D, const ParsedAttr &AL);
+  void CheckSMEFunctionDefAttributes(const FunctionDecl *FD);
 };
 
 SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD);
diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp
index 411baa066f7097..eafd43eb979ba0 100644
--- a/clang/lib/Sema/SemaARM.cpp
+++ b/clang/lib/Sema/SemaARM.cpp
@@ -1328,4 +1328,57 @@ void SemaARM::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
                  ARMInterruptAttr(getASTContext(), AL, Kind));
 }
 
+// Check if the function definition uses any AArch64 SME features without
+// having the '+sme' feature enabled and warn user if sme locally streaming
+// function returns or uses arguments with VL-based types.
+void SemaARM::CheckSMEFunctionDefAttributes(const FunctionDecl *FD) {
+  const auto *Attr = FD->getAttr<ArmNewAttr>();
+  bool UsesSM = FD->hasAttr<ArmLocallyStreamingAttr>();
+  bool UsesZA = Attr && Attr->isNewZA();
+  bool UsesZT0 = Attr && Attr->isNewZT0();
+
+  if (FD->hasAttr<ArmLocallyStreamingAttr>()) {
+    if (FD->getReturnType()->isSizelessVectorType())
+      Diag(FD->getLocation(),
+           diag::warn_sme_locally_streaming_has_vl_args_returns)
+          << /*IsArg=*/false;
+    if (llvm::any_of(FD->parameters(), [](ParmVarDecl *P) {
+          return P->getOriginalType()->isSizelessVectorType();
+        }))
+      Diag(FD->getLocation(),
+           diag::warn_sme_locally_streaming_has_vl_args_returns)
+          << /*IsArg=*/true;
+  }
+  if (const auto *FPT = FD->getType()->getAs<FunctionProtoType>()) {
+    FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
+    UsesSM |= EPI.AArch64SMEAttributes & FunctionType::SME_PStateSMEnabledMask;
+    UsesZA |= FunctionType::getArmZAState(EPI.AArch64SMEAttributes) !=
+              FunctionType::ARM_None;
+    UsesZT0 |= FunctionType::getArmZT0State(EPI.AArch64SMEAttributes) !=
+               FunctionType::ARM_None;
+  }
+
+  ASTContext &Context = getASTContext();
+  if (UsesSM || UsesZA) {
+    llvm::StringMap<bool> FeatureMap;
+    Context.getFunctionFeatureMap(FeatureMap, FD);
+    if (!FeatureMap.contains("sme")) {
+      if (UsesSM)
+        Diag(FD->getLocation(),
+             diag::err_sme_definition_using_sm_in_non_sme_target);
+      else
+        Diag(FD->getLocation(),
+             diag::err_sme_definition_using_za_in_non_sme_target);
+    }
+  }
+  if (UsesZT0) {
+    llvm::StringMap<bool> FeatureMap;
+    Context.getFunctionFeatureMap(FeatureMap, FD);
+    if (!FeatureMap.contains("sme2")) {
+      Diag(FD->getLocation(),
+           diag::err_sme_definition_using_zt0_in_non_sme2_target);
+    }
+  }
+}
+
 } // namespace clang
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 4001c4d263f1d2..1603b622a4faf0 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -45,6 +45,7 @@
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaARM.h"
 #include "clang/Sema/SemaCUDA.h"
 #include "clang/Sema/SemaHLSL.h"
 #include "clang/Sema/SemaInternal.h"
@@ -12286,58 +12287,8 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
     }
   }
 
-  // Check if the function definition uses any AArch64 SME features without
-  // having the '+sme' feature enabled and warn user if sme locally streaming
-  // function returns or uses arguments with VL-based types.
-  if (DeclIsDefn) {
-    const auto *Attr = NewFD->getAttr<ArmNewAttr>();
-    bool UsesSM = NewFD->hasAttr<ArmLocallyStreamingAttr>();
-    bool UsesZA = Attr && Attr->isNewZA();
-    bool UsesZT0 = Attr && Attr->isNewZT0();
-
-    if (NewFD->hasAttr<ArmLocallyStreamingAttr>()) {
-      if (NewFD->getReturnType()->isSizelessVectorType())
-        Diag(NewFD->getLocation(),
-             diag::warn_sme_locally_streaming_has_vl_args_returns)
-            << /*IsArg=*/false;
-      if (llvm::any_of(NewFD->parameters(), [](ParmVarDecl *P) {
-            return P->getOriginalType()->isSizelessVectorType();
-          }))
-        Diag(NewFD->getLocation(),
-             diag::warn_sme_locally_streaming_has_vl_args_returns)
-            << /*IsArg=*/true;
-    }
-    if (const auto *FPT = NewFD->getType()->getAs<FunctionProtoType>()) {
-      FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
-      UsesSM |=
-          EPI.AArch64SMEAttributes & FunctionType::SME_PStateSMEnabledMask;
-      UsesZA |= FunctionType::getArmZAState(EPI.AArch64SMEAttributes) !=
-                FunctionType::ARM_None;
-      UsesZT0 |= FunctionType::getArmZT0State(EPI.AArch64SMEAttributes) !=
-                 FunctionType::ARM_None;
-    }
-
-    if (UsesSM || UsesZA) {
-      llvm::StringMap<bool> FeatureMap;
-      Context.getFunctionFeatureMap(FeatureMap, NewFD);
-      if (!FeatureMap.contains("sme")) {
-        if (UsesSM)
-          Diag(NewFD->getLocation(),
-               diag::err_sme_definition_using_sm_in_non_sme_target);
-        else
-          Diag(NewFD->getLocation(),
-               diag::err_sme_definition_using_za_in_non_sme_target);
-      }
-    }
-    if (UsesZT0) {
-      llvm::StringMap<bool> FeatureMap;
-      Context.getFunctionFeatureMap(FeatureMap, NewFD);
-      if (!FeatureMap.contains("sme2")) {
-        Diag(NewFD->getLocation(),
-             diag::err_sme_definition_using_zt0_in_non_sme2_target);
-      }
-    }
-  }
+  if (DeclIsDefn && Context.getTargetInfo().getTriple().isAArch64())
+    ARM().CheckSMEFunctionDefAttributes(NewFD);
 
   return Redeclaration;
 }
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 3ee26ebabcfdd5..e599ff3731a314 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -41,6 +41,7 @@
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaARM.h"
 #include "clang/Sema/SemaCUDA.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaObjC.h"
@@ -1854,27 +1855,8 @@ bool Sema::CheckConstexprFunctionDefinition(const FunctionDecl *NewFD,
     }
   }
 
-  if (Context.getTargetInfo().getTriple().isAArch64()) {
-    const auto *Attr = NewFD->getAttr<ArmNewAttr>();
-    bool LocallyStreaming = NewFD->hasAttr<ArmLocallyStreamingAttr>();
-    llvm::StringMap<bool> FeatureMap;
-    Context.getFunctionFeatureMap(FeatureMap, NewFD);
-    if (!FeatureMap.contains("sme") && LocallyStreaming) {
-      Diag(NewFD->getLocation(),
-           diag::err_sme_definition_using_sm_in_non_sme_target);
-      return false;
-    }
-    if (Attr && Attr->isNewZA() && !FeatureMap.contains("sme")) {
-      Diag(NewFD->getLocation(),
-           diag::err_sme_definition_using_za_in_non_sme_target);
-      return false;
-    }
-    if (Attr && Attr->isNewZT0() && !FeatureMap.contains("sme2")) {
-      Diag(NewFD->getLocation(),
-           diag::err_sme_definition_using_zt0_in_non_sme2_target);
-      return false;
-    }
-  }
+  if (Context.getTargetInfo().getTriple().isAArch64())
+    ARM().CheckSMEFunctionDefAttributes(NewFD);
 
   // - each of its parameter types shall be a literal type; (removed in C++23)
   if (!getLangOpts().CPlusPlus23 &&
diff --git a/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp b/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
index a046b5aa1325cc..02ebfc8060f37e 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
+++ b/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
@@ -49,7 +49,7 @@ void streaming_compatible_def2(void (*streaming_fn_ptr)(void) __arm_streaming,
 int streaming_decl_ret_int() __arm_streaming;
 int x = streaming_decl_ret_int(); // expected-error {{call to a streaming function requires 'sme'}}
 
-void sme_attrs_method_decls() {
+void sme_attrs_lambdas() {
   [&] __arm_locally_streaming () { return; }();  // expected-error {{function executed in streaming-SVE mode requires 'sme'}}
   [&] __arm_new("za") () { return; }();  // expected-error {{function using ZA state requires 'sme'}}
   [&] __arm_new("zt0") () { return; }();  // expected-error {{function using ZT0 state requires 'sme2'}}

>From 02658f77912b75bed88571973e263760f6759d3b Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Mon, 6 Jan 2025 16:51:43 +0000
Subject: [PATCH 3/4] - Mark CheckSMEFunctionDefAttributes as static - Move
 CheckSMEFunctionDefAttributes call to ActOnStartOfLambdaDefinition

---
 clang/include/clang/Sema/SemaARM.h            |  3 ++-
 clang/lib/Sema/SemaARM.cpp                    | 24 +++++++++----------
 clang/lib/Sema/SemaDecl.cpp                   |  2 +-
 clang/lib/Sema/SemaDeclCXX.cpp                |  4 ----
 clang/lib/Sema/SemaLambda.cpp                 |  4 ++++
 ...-sme-func-attrs-without-target-feature.cpp |  6 ++---
 6 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/clang/include/clang/Sema/SemaARM.h b/clang/include/clang/Sema/SemaARM.h
index 08b03af7fd4bc6..f648cdf35a30cc 100644
--- a/clang/include/clang/Sema/SemaARM.h
+++ b/clang/include/clang/Sema/SemaARM.h
@@ -79,7 +79,8 @@ class SemaARM : public SemaBase {
   void handleNewAttr(Decl *D, const ParsedAttr &AL);
   void handleCmseNSEntryAttr(Decl *D, const ParsedAttr &AL);
   void handleInterruptAttr(Decl *D, const ParsedAttr &AL);
-  void CheckSMEFunctionDefAttributes(const FunctionDecl *FD);
+
+  static void CheckSMEFunctionDefAttributes(const FunctionDecl *FD, Sema &S);
 };
 
 SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD);
diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp
index eafd43eb979ba0..a99ef6970a04e6 100644
--- a/clang/lib/Sema/SemaARM.cpp
+++ b/clang/lib/Sema/SemaARM.cpp
@@ -1331,7 +1331,7 @@ void SemaARM::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
 // Check if the function definition uses any AArch64 SME features without
 // having the '+sme' feature enabled and warn user if sme locally streaming
 // function returns or uses arguments with VL-based types.
-void SemaARM::CheckSMEFunctionDefAttributes(const FunctionDecl *FD) {
+void SemaARM::CheckSMEFunctionDefAttributes(const FunctionDecl *FD, Sema &S) {
   const auto *Attr = FD->getAttr<ArmNewAttr>();
   bool UsesSM = FD->hasAttr<ArmLocallyStreamingAttr>();
   bool UsesZA = Attr && Attr->isNewZA();
@@ -1339,14 +1339,14 @@ void SemaARM::CheckSMEFunctionDefAttributes(const FunctionDecl *FD) {
 
   if (FD->hasAttr<ArmLocallyStreamingAttr>()) {
     if (FD->getReturnType()->isSizelessVectorType())
-      Diag(FD->getLocation(),
-           diag::warn_sme_locally_streaming_has_vl_args_returns)
+      S.Diag(FD->getLocation(),
+             diag::warn_sme_locally_streaming_has_vl_args_returns)
           << /*IsArg=*/false;
     if (llvm::any_of(FD->parameters(), [](ParmVarDecl *P) {
           return P->getOriginalType()->isSizelessVectorType();
         }))
-      Diag(FD->getLocation(),
-           diag::warn_sme_locally_streaming_has_vl_args_returns)
+      S.Diag(FD->getLocation(),
+             diag::warn_sme_locally_streaming_has_vl_args_returns)
           << /*IsArg=*/true;
   }
   if (const auto *FPT = FD->getType()->getAs<FunctionProtoType>()) {
@@ -1358,25 +1358,25 @@ void SemaARM::CheckSMEFunctionDefAttributes(const FunctionDecl *FD) {
                FunctionType::ARM_None;
   }
 
-  ASTContext &Context = getASTContext();
+  ASTContext &Context = S.getASTContext();
   if (UsesSM || UsesZA) {
     llvm::StringMap<bool> FeatureMap;
     Context.getFunctionFeatureMap(FeatureMap, FD);
     if (!FeatureMap.contains("sme")) {
       if (UsesSM)
-        Diag(FD->getLocation(),
-             diag::err_sme_definition_using_sm_in_non_sme_target);
+        S.Diag(FD->getLocation(),
+               diag::err_sme_definition_using_sm_in_non_sme_target);
       else
-        Diag(FD->getLocation(),
-             diag::err_sme_definition_using_za_in_non_sme_target);
+        S.Diag(FD->getLocation(),
+               diag::err_sme_definition_using_za_in_non_sme_target);
     }
   }
   if (UsesZT0) {
     llvm::StringMap<bool> FeatureMap;
     Context.getFunctionFeatureMap(FeatureMap, FD);
     if (!FeatureMap.contains("sme2")) {
-      Diag(FD->getLocation(),
-           diag::err_sme_definition_using_zt0_in_non_sme2_target);
+      S.Diag(FD->getLocation(),
+             diag::err_sme_definition_using_zt0_in_non_sme2_target);
     }
   }
 }
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 1603b622a4faf0..a46371227300a1 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12288,7 +12288,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
   }
 
   if (DeclIsDefn && Context.getTargetInfo().getTriple().isAArch64())
-    ARM().CheckSMEFunctionDefAttributes(NewFD);
+    SemaARM::CheckSMEFunctionDefAttributes(NewFD, *this);
 
   return Redeclaration;
 }
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index e599ff3731a314..c5a72cf812ebc9 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -41,7 +41,6 @@
 #include "clang/Sema/ParsedTemplate.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
-#include "clang/Sema/SemaARM.h"
 #include "clang/Sema/SemaCUDA.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaObjC.h"
@@ -1855,9 +1854,6 @@ bool Sema::CheckConstexprFunctionDefinition(const FunctionDecl *NewFD,
     }
   }
 
-  if (Context.getTargetInfo().getTriple().isAArch64())
-    ARM().CheckSMEFunctionDefAttributes(NewFD);
-
   // - each of its parameter types shall be a literal type; (removed in C++23)
   if (!getLangOpts().CPlusPlus23 &&
       !CheckConstexprParameterTypes(*this, NewFD, Kind))
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index a67c0b2b367d1a..044df8520c9fe3 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -21,6 +21,7 @@
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaARM.h"
 #include "clang/Sema/SemaCUDA.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaOpenMP.h"
@@ -1454,6 +1455,9 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
   // Attributes on the lambda apply to the method.
   ProcessDeclAttributes(CurScope, Method, ParamInfo);
 
+  if (Context.getTargetInfo().getTriple().isAArch64())
+    SemaARM::CheckSMEFunctionDefAttributes(Method, *this);
+
   // CUDA lambdas get implicit host and device attributes.
   if (getLangOpts().CUDA)
     CUDA().SetLambdaAttrs(Method);
diff --git a/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp b/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
index 02ebfc8060f37e..2ba266a93f94ff 100644
--- a/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
+++ b/clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp
@@ -50,7 +50,7 @@ int streaming_decl_ret_int() __arm_streaming;
 int x = streaming_decl_ret_int(); // expected-error {{call to a streaming function requires 'sme'}}
 
 void sme_attrs_lambdas() {
-  [&] __arm_locally_streaming () { return; }();  // expected-error {{function executed in streaming-SVE mode requires 'sme'}}
-  [&] __arm_new("za") () { return; }();  // expected-error {{function using ZA state requires 'sme'}}
-  [&] __arm_new("zt0") () { return; }();  // expected-error {{function using ZT0 state requires 'sme2'}}
+  [] __arm_locally_streaming () { return; }();  // expected-error {{function executed in streaming-SVE mode requires 'sme'}}
+  [] __arm_new("za") () { return; }();  // expected-error {{function using ZA state requires 'sme'}}
+  [] __arm_new("zt0") () { return; }();  // expected-error {{function using ZT0 state requires 'sme2'}}
 }

>From d47933c2e71e09659e41dd0dfa665d9a6ddb53fe Mon Sep 17 00:00:00 2001
From: Kerry McLaughlin <kerry.mclaughlin at arm.com>
Date: Wed, 8 Jan 2025 17:30:01 +0000
Subject: [PATCH 4/4] - Removed static from CheckSMEFunctionDefAttributes

---
 clang/include/clang/Sema/SemaARM.h |  2 +-
 clang/lib/Sema/SemaARM.cpp         | 24 ++++++++++++------------
 clang/lib/Sema/SemaDecl.cpp        |  2 +-
 clang/lib/Sema/SemaLambda.cpp      |  2 +-
 4 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/clang/include/clang/Sema/SemaARM.h b/clang/include/clang/Sema/SemaARM.h
index f648cdf35a30cc..7beb1906a122fe 100644
--- a/clang/include/clang/Sema/SemaARM.h
+++ b/clang/include/clang/Sema/SemaARM.h
@@ -80,7 +80,7 @@ class SemaARM : public SemaBase {
   void handleCmseNSEntryAttr(Decl *D, const ParsedAttr &AL);
   void handleInterruptAttr(Decl *D, const ParsedAttr &AL);
 
-  static void CheckSMEFunctionDefAttributes(const FunctionDecl *FD, Sema &S);
+  void CheckSMEFunctionDefAttributes(const FunctionDecl *FD);
 };
 
 SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD);
diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp
index a99ef6970a04e6..eafd43eb979ba0 100644
--- a/clang/lib/Sema/SemaARM.cpp
+++ b/clang/lib/Sema/SemaARM.cpp
@@ -1331,7 +1331,7 @@ void SemaARM::handleInterruptAttr(Decl *D, const ParsedAttr &AL) {
 // Check if the function definition uses any AArch64 SME features without
 // having the '+sme' feature enabled and warn user if sme locally streaming
 // function returns or uses arguments with VL-based types.
-void SemaARM::CheckSMEFunctionDefAttributes(const FunctionDecl *FD, Sema &S) {
+void SemaARM::CheckSMEFunctionDefAttributes(const FunctionDecl *FD) {
   const auto *Attr = FD->getAttr<ArmNewAttr>();
   bool UsesSM = FD->hasAttr<ArmLocallyStreamingAttr>();
   bool UsesZA = Attr && Attr->isNewZA();
@@ -1339,14 +1339,14 @@ void SemaARM::CheckSMEFunctionDefAttributes(const FunctionDecl *FD, Sema &S) {
 
   if (FD->hasAttr<ArmLocallyStreamingAttr>()) {
     if (FD->getReturnType()->isSizelessVectorType())
-      S.Diag(FD->getLocation(),
-             diag::warn_sme_locally_streaming_has_vl_args_returns)
+      Diag(FD->getLocation(),
+           diag::warn_sme_locally_streaming_has_vl_args_returns)
           << /*IsArg=*/false;
     if (llvm::any_of(FD->parameters(), [](ParmVarDecl *P) {
           return P->getOriginalType()->isSizelessVectorType();
         }))
-      S.Diag(FD->getLocation(),
-             diag::warn_sme_locally_streaming_has_vl_args_returns)
+      Diag(FD->getLocation(),
+           diag::warn_sme_locally_streaming_has_vl_args_returns)
           << /*IsArg=*/true;
   }
   if (const auto *FPT = FD->getType()->getAs<FunctionProtoType>()) {
@@ -1358,25 +1358,25 @@ void SemaARM::CheckSMEFunctionDefAttributes(const FunctionDecl *FD, Sema &S) {
                FunctionType::ARM_None;
   }
 
-  ASTContext &Context = S.getASTContext();
+  ASTContext &Context = getASTContext();
   if (UsesSM || UsesZA) {
     llvm::StringMap<bool> FeatureMap;
     Context.getFunctionFeatureMap(FeatureMap, FD);
     if (!FeatureMap.contains("sme")) {
       if (UsesSM)
-        S.Diag(FD->getLocation(),
-               diag::err_sme_definition_using_sm_in_non_sme_target);
+        Diag(FD->getLocation(),
+             diag::err_sme_definition_using_sm_in_non_sme_target);
       else
-        S.Diag(FD->getLocation(),
-               diag::err_sme_definition_using_za_in_non_sme_target);
+        Diag(FD->getLocation(),
+             diag::err_sme_definition_using_za_in_non_sme_target);
     }
   }
   if (UsesZT0) {
     llvm::StringMap<bool> FeatureMap;
     Context.getFunctionFeatureMap(FeatureMap, FD);
     if (!FeatureMap.contains("sme2")) {
-      S.Diag(FD->getLocation(),
-             diag::err_sme_definition_using_zt0_in_non_sme2_target);
+      Diag(FD->getLocation(),
+           diag::err_sme_definition_using_zt0_in_non_sme2_target);
     }
   }
 }
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a46371227300a1..1603b622a4faf0 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12288,7 +12288,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
   }
 
   if (DeclIsDefn && Context.getTargetInfo().getTriple().isAArch64())
-    SemaARM::CheckSMEFunctionDefAttributes(NewFD, *this);
+    ARM().CheckSMEFunctionDefAttributes(NewFD);
 
   return Redeclaration;
 }
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 044df8520c9fe3..691c2e27ae6ac7 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1456,7 +1456,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
   ProcessDeclAttributes(CurScope, Method, ParamInfo);
 
   if (Context.getTargetInfo().getTriple().isAArch64())
-    SemaARM::CheckSMEFunctionDefAttributes(Method, *this);
+    ARM().CheckSMEFunctionDefAttributes(Method);
 
   // CUDA lambdas get implicit host and device attributes.
   if (getLangOpts().CUDA)



More information about the cfe-commits mailing list