Author: Doug Wyatt Date: 2024-11-18T16:04:10-08:00 New Revision: 39bdf7a9db64927dfa4ad7fa85bcdf7a77a32ece
URL: https://github.com/llvm/llvm-project/commit/39bdf7a9db64927dfa4ad7fa85bcdf7a77a32ece DIFF: https://github.com/llvm/llvm-project/commit/39bdf7a9db64927dfa4ad7fa85bcdf7a77a32ece.diff LOG: [Clang] SemaFunctionEffects: Fix bug where lambdas produced by template expansion weren't verified. (#116505) --------- Co-authored-by: Doug Wyatt <dwy...@apple.com> Added: Modified: clang/lib/Sema/SemaFunctionEffects.cpp clang/lib/Sema/SemaLambda.cpp clang/test/Sema/attr-nonblocking-constraints.cpp Removed: ################################################################################ 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..bbc909f627f4c3 100644 --- a/clang/test/Sema/attr-nonblocking-constraints.cpp +++ b/clang/test/Sema/attr-nonblocking-constraints.cpp @@ -144,6 +144,41 @@ 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); +} + +// Templated function and lambda. +template <typename T> +void TemplatedFunc(T x) [[clang::nonblocking]] { + auto* ptr = new T; // expected-warning {{function with 'nonblocking' attribute must not allocate or deallocate memory}} +} + +void nb9b() [[clang::nonblocking]] { + TemplatedFunc(42); // expected-note {{in template expansion here}} + + auto foo = [](auto x) [[clang::nonblocking]] { + auto* ptr = new int; // expected-warning {{lambda with 'nonblocking' attribute must not allocate or deallocate memory}} + return x; + }; + + // Note that foo() won't be validated unless instantiated. + foo(42); +} + void nb10( void (*fp1)(), // expected-note {{function pointer cannot be inferred 'nonblocking'}} void (*fp2)() [[clang::nonblocking]] _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits