https://github.com/ketjandr created
https://github.com/llvm/llvm-project/pull/217194
This PR fixes a regression from #215173 where an `always_inline` lambda on a
`#pragma clang optimize off` will throw a compiler error. For example,
```
#pragma clang optimize off
// 1. function:
__attribute__((always_inline)) void front_func() {}
// 2. lambda:
auto trailing_lambda = []() __attribute__((always_inline)) { return 42; };
```
causes only an error for the lambda, not function:
```
/tmp/repro.cpp:7:44: error: 'always_inline' and '__noinline__' attributes are
not compatible
7 | auto trailing_lambda = []() __attribute__((always_inline)) { return 42;
};
| ^
/tmp/repro.cpp:1:15: note: conflicting attribute is here
1 | #pragma clang optimize off
| ^
1 error generated
```
This would fail loudly as d3d3d4d502fc8728ecccd1e1dc283af7dd52d5d4 enforces
mutual exclusions between `always_inline` and `no_inline`.
The fix here is to ensure lambdas follow the same pattern as functions. For
functions, in `SemaDecl.cpp` we called `ProcessDeclAttributes()` which adds
`always_inline` before `AddRangeBasedOptNone()` (which guards against adding
`no_inline` if `always_inline` is already present). Lambdas had the order
reversed however, so this patch reorders these correctly.
>From 99e2b0060a5eb8f649753ee34bb9dd2fd9980e7c Mon Sep 17 00:00:00 2001
From: Kenzo <[email protected]>
Date: Tue, 18 Aug 2026 22:05:15 -0400
Subject: [PATCH] [Clang][Sema] Fix lambda attribute processing order with
clang optimize off
---
clang/lib/Sema/SemaLambda.cpp | 8 ++++----
.../CodeGenCXX/optnone-pragma-optimize-off.cpp | 18 +++++++++++++++++-
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index b97c6d8b95f62..6c9a837cc8a79 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1513,10 +1513,6 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer
&Intro,
CheckCXXDefaultArguments(Method);
- // This represents the function body for the lambda function, check if we
- // have to apply optnone due to a pragma.
- AddRangeBasedOptnone(Method);
-
// code_seg attribute on lambda apply to the method.
if (Attr *A = getImplicitCodeSegOrSectionAttrForFunction(
Method, /*IsDefinition=*/true))
@@ -1525,6 +1521,10 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer
&Intro,
// Attributes on the lambda apply to the method.
ProcessDeclAttributes(CurScope, Method, ParamInfo);
+ // This represents the function body for the lambda function, check if we
+ // have to apply optnone due to a pragma.
+ AddRangeBasedOptnone(Method);
+
if (Context.getTargetInfo().getTriple().isAArch64())
ARM().CheckSMEFunctionDefAttributes(Method);
diff --git a/clang/test/CodeGenCXX/optnone-pragma-optimize-off.cpp
b/clang/test/CodeGenCXX/optnone-pragma-optimize-off.cpp
index d750c4c2848cb..2819db70fb896 100644
--- a/clang/test/CodeGenCXX/optnone-pragma-optimize-off.cpp
+++ b/clang/test/CodeGenCXX/optnone-pragma-optimize-off.cpp
@@ -13,4 +13,20 @@ void foo(int p) {
_Pragma("clang optimize on")
-// CHECK: attributes #[[LAMBDA_ATR]] = { {{.*}} optnone {{.*}} }
\ No newline at end of file
+// An always_inline lambda should not have noinline and optnone and should
+// compile under _Pragma("clang optimize off")
+_Pragma("clang optimize off")
+
+__attribute__((always_inline)) void bar() {}
+// CHECK: define {{.*}}void @_Z3barv() #[[ALWAYSINLINE:[0-9]+]]
+
+auto lambda = []() __attribute__((always_inline)) { return 42; };
+// CHECK: define {{.*}} @"_ZNK3$_1clEv"({{.*}}) #[[ALWAYSINLINE]]
+
+int caller() {
+ bar();
+ return lambda();
+}
+
+// CHECK: attributes #[[LAMBDA_ATR]] = { {{.*}} optnone {{.*}} }
+// CHECK: attributes #[[ALWAYSINLINE]] = {{{.*}}alwaysinline{{.*}}}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits