[clang] [Clang] SemaFunctionEffects: Fix bug where lambdas produced by template expansion weren't verified. (PR #116505)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Nov 16 12:11:21 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Doug Wyatt (dougsonos)
<details>
<summary>Changes</summary>
Lambdas are added to the list of Decls to verify using `Sema::maybeAddDeclWithEffects()`. Up until now this call was in `ActOnLambdaExpr`, which happens in the context of a template but not in the context of template expansion.
Template expansion calls `BuildLambdaExpr`, so move the call to `Sema::maybeAddDeclWithEffects()` there.
Fixing this created a not-previously-seen situation where the custom "In template expansion here" diagnostic didn't have a valid location. This breaks tests because there's a note with no location. For now I've just skipped emitting the diagnostic but maybe there's a better solution.
---
Full diff: https://github.com/llvm/llvm-project/pull/116505.diff
3 Files Affected:
- (modified) clang/lib/Sema/SemaFunctionEffects.cpp (+2-1)
- (modified) clang/lib/Sema/SemaLambda.cpp (+1-2)
- (modified) clang/test/Sema/attr-nonblocking-constraints.cpp (+17)
``````````diff
diff --git a/clang/lib/Sema/SemaFunctionEffects.cpp b/clang/lib/Sema/SemaFunctionEffects.cpp
index 4b5ddb74b1262f..6fe4d2353a2282 100644
--- a/clang/lib/Sema/SemaFunctionEffects.cpp
+++ b/clang/lib/Sema/SemaFunctionEffects.cpp
@@ -807,7 +807,8 @@ class Analyzer {
auto MaybeAddTemplateNote = [&](const Decl *D) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- while (FD != nullptr && FD->isTemplateInstantiation()) {
+ while (FD != nullptr && FD->isTemplateInstantiation() &&
+ FD->getPointOfInstantiation().isValid()) {
S.Diag(FD->getPointOfInstantiation(),
diag::note_func_effect_from_template);
FD = FD->getTemplateInstantiationPattern();
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index e7afa0f4c81fc4..a67c0b2b367d1a 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1950,8 +1950,6 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body) {
LambdaScopeInfo LSI = *cast<LambdaScopeInfo>(FunctionScopes.back());
ActOnFinishFunctionBody(LSI.CallOperator, Body);
- maybeAddDeclWithEffects(LSI.CallOperator);
-
return BuildLambdaExpr(StartLoc, Body->getEndLoc(), &LSI);
}
@@ -2284,6 +2282,7 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
case ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed:
break;
}
+ maybeAddDeclWithEffects(LSI->CallOperator);
}
return MaybeBindToTemporary(Lambda);
diff --git a/clang/test/Sema/attr-nonblocking-constraints.cpp b/clang/test/Sema/attr-nonblocking-constraints.cpp
index cc9108c0a4fbd6..87cbcc9713859f 100644
--- a/clang/test/Sema/attr-nonblocking-constraints.cpp
+++ b/clang/test/Sema/attr-nonblocking-constraints.cpp
@@ -144,6 +144,23 @@ void nb9() [[clang::nonblocking]]
expected-note {{in template expansion here}}
}
+// Make sure we verify lambdas produced from template expansions.
+struct HasTemplatedLambda {
+ void (*fptr)() [[clang::nonblocking]];
+
+ template <typename C>
+ HasTemplatedLambda(const C&)
+ : fptr{ []() [[clang::nonblocking]] {
+ auto* y = new int; // expected-warning {{lambda with 'nonblocking' attribute must not allocate or deallocate memory}}
+ } }
+ {}
+};
+
+void nb9a()
+{
+ HasTemplatedLambda bad(42);
+}
+
void nb10(
void (*fp1)(), // expected-note {{function pointer cannot be inferred 'nonblocking'}}
void (*fp2)() [[clang::nonblocking]]
``````````
</details>
https://github.com/llvm/llvm-project/pull/116505
More information about the cfe-commits
mailing list