Skip to content

Commit 4d218ca

Browse files
dougsonosDoug Wyatt
andauthored
[Clang] [Sema] Effects: Correctly detect (x ? a : b) as nonblocking when a and b are (#111224)
Correctly detect `(x ? a : b)` as nonblocking when `a` and `b` are. Use `FunctionEffectsRef::get` to get to the actual effect set instead of trying to retrieve it manually via the `FunctionProtoType` as we may have to look through function pointers etc. in some cases. --------- Co-authored-by: Doug Wyatt <[email protected]>
1 parent a3a253d commit 4d218ca

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

clang/lib/Sema/SemaFunctionEffects.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,15 +1048,14 @@ class Analyzer {
10481048
}
10491049

10501050
void checkIndirectCall(CallExpr *Call, QualType CalleeType) {
1051-
auto *FPT =
1052-
CalleeType->getAs<FunctionProtoType>(); // Null if FunctionType.
10531051
FunctionEffectKindSet CalleeEffects;
1054-
if (FPT)
1055-
CalleeEffects.insert(FPT->getFunctionEffects());
1052+
if (FunctionEffectsRef Effects = FunctionEffectsRef::get(CalleeType);
1053+
!Effects.empty())
1054+
CalleeEffects.insert(Effects);
10561055

10571056
auto Check1Effect = [&](FunctionEffect Effect, bool Inferring) {
1058-
if (FPT == nullptr || Effect.shouldDiagnoseFunctionCall(
1059-
/*direct=*/false, CalleeEffects))
1057+
if (Effect.shouldDiagnoseFunctionCall(
1058+
/*direct=*/false, CalleeEffects))
10601059
addViolation(Inferring, Effect, ViolationID::CallsExprWithoutEffect,
10611060
Call->getBeginLoc());
10621061
};

clang/test/Sema/attr-nonblocking-constraints.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,17 @@ void nb10(
156156
static_cast<void (*)()>(fp1)(); // expected-warning {{function with 'nonblocking' attribute must not call non-'nonblocking' expression}}
157157
}
158158

159+
// Expression involving indirection
160+
int nb10a() [[clang::nonblocking]];
161+
int nb10b() [[clang::nonblocking]];
162+
int blocking();
163+
164+
int nb10c(bool x) [[clang::nonblocking]]
165+
{
166+
int y = (x ? nb10a : blocking)(); // expected-warning {{attribute 'nonblocking' should not be added via type conversion}}
167+
return (x ? nb10a : nb10b)(); // No diagnostic.
168+
}
169+
159170
// Interactions with nonblocking(false)
160171
void nb11_no_inference_1() [[clang::nonblocking(false)]] // expected-note {{function does not permit inference of 'nonblocking'}}
161172
{

0 commit comments

Comments
 (0)