[Clang] SemaFunctionEffects: Fix bug where lambdas produced by template expansion weren't verified. (#116505)
--------- Co-authored-by: Doug Wyatt <dwyatt@apple.com>
This commit is contained in:
@@ -807,7 +807,8 @@ private:
|
||||
|
||||
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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]]
|
||||
|
||||
Reference in New Issue
Block a user