Skip to content

Conversation

@dougsonos
Copy link
Contributor

@dougsonos dougsonos commented Oct 5, 2024

Fix: Effect analysis: correctly detect (x ? a : b) as nonblocking when a and b are

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Oct 5, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 5, 2024

@llvm/pr-subscribers-clang

Author: Doug Wyatt (dougsonos)

Changes

Fix: Effect analysis: correctly detect (f ? a : b) as nonblocking when a and b are


Full diff: https://github.com/llvm/llvm-project/pull/111224.diff

2 Files Affected:

  • (modified) clang/lib/Sema/SemaFunctionEffects.cpp (+5-6)
  • (modified) clang/test/Sema/attr-nonblocking-constraints.cpp (+10)
diff --git a/clang/lib/Sema/SemaFunctionEffects.cpp b/clang/lib/Sema/SemaFunctionEffects.cpp
index 0fb18d207a50ba..0ac5de29f66aa7 100644
--- a/clang/lib/Sema/SemaFunctionEffects.cpp
+++ b/clang/lib/Sema/SemaFunctionEffects.cpp
@@ -1048,15 +1048,14 @@ class Analyzer {
     }
 
     void checkIndirectCall(CallExpr *Call, QualType CalleeType) {
-      auto *FPT =
-          CalleeType->getAs<FunctionProtoType>(); // Null if FunctionType.
       FunctionEffectKindSet CalleeEffects;
-      if (FPT)
-        CalleeEffects.insert(FPT->getFunctionEffects());
+      if (FunctionEffectsRef Effects = FunctionEffectsRef::get(CalleeType);
+          !Effects.empty())
+        CalleeEffects.insert(Effects);
 
       auto Check1Effect = [&](FunctionEffect Effect, bool Inferring) {
-        if (FPT == nullptr || Effect.shouldDiagnoseFunctionCall(
-                                  /*direct=*/false, CalleeEffects))
+        if (Effect.shouldDiagnoseFunctionCall(
+                /*direct=*/false, CalleeEffects))
           addViolation(Inferring, Effect, ViolationID::CallsExprWithoutEffect,
                        Call->getBeginLoc());
       };
diff --git a/clang/test/Sema/attr-nonblocking-constraints.cpp b/clang/test/Sema/attr-nonblocking-constraints.cpp
index c694860069c960..ff8caf0e573403 100644
--- a/clang/test/Sema/attr-nonblocking-constraints.cpp
+++ b/clang/test/Sema/attr-nonblocking-constraints.cpp
@@ -156,6 +156,16 @@ void nb10(
 	static_cast<void (*)()>(fp1)(); // expected-warning {{function with 'nonblocking' attribute must not call non-'nonblocking' expression}}
 }
 
+// Expression involving indirection
+int nb10a() [[clang::nonblocking]];
+int nb10b() [[clang::nonblocking]];
+
+int nb10c(bool x) [[clang::nonblocking]]
+{
+	// Warns that the expression is not nonblocking.
+	return (x ? nb10a : nb10b)();
+}
+
 // Interactions with nonblocking(false)
 void nb11_no_inference_1() [[clang::nonblocking(false)]] // expected-note {{function does not permit inference of 'nonblocking'}}
 {

FunctionEffectKindSet CalleeEffects;
if (FPT)
CalleeEffects.insert(FPT->getFunctionEffects());
if (FunctionEffectsRef Effects = FunctionEffectsRef::get(CalleeType);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FunctionEffectsRef::get() knows how to pick through indirections (references/pointers) to get to a FunctionProtoType so just reuse that.

auto Check1Effect = [&](FunctionEffect Effect, bool Inferring) {
if (FPT == nullptr || Effect.shouldDiagnoseFunctionCall(
/*direct=*/false, CalleeEffects))
if (Effect.shouldDiagnoseFunctionCall(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check for a null FPT is/was superfluous; in that case the callee never has any declared effects and shouldDiagnoseFunctionCall will complain.

@dougsonos dougsonos changed the title Effect analysis: correctly detect (f ? a : b) as nonblocking when a and b are Effect analysis: correctly detect (x ? a : b) as nonblocking when a and b are Oct 5, 2024
@dougsonos
Copy link
Contributor Author

@cjappl @Sirraide would appreciate what I hope will be a quick review on a small fix.

Copy link
Contributor

@cjappl cjappl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Will let a little time pass to let Sirraide chime in, because this section of the code isn't my forte. If you want this merged ASAP @dougsonos and you feel confident in it, ping me and I can merge.

Copy link
Member

@Sirraide Sirraide left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Sirraide Sirraide merged commit 4d218ca into llvm:main Oct 8, 2024
@Sirraide
Copy link
Member

Sirraide commented Oct 8, 2024

@dougsonos Maybe you should ask for commit access since you’ll likely be contributing more patches to this in the future as I understand it?

CC @AaronBallman Does that still work like it used to or did your maintainers rfc change something about that too?

@Sirraide
Copy link
Member

Sirraide commented Oct 8, 2024

Oh, also, are there any other places where we should maybe be using FunctionEffectsRef::get()?

@dougsonos
Copy link
Contributor Author

Oh, also, are there any other places where we should maybe be using FunctionEffectsRef::get()?

Good question. I looked for other uses of QualType and getType() in SemaFunctionEffects, but this is the only spot (checkIndirectCall) where we are interested in obtaining effects from an expression which didn't come from a Decl. If there were a Decl it would have taken an earlier branch in VisitCallExpr, where we build a CallableInfo, whose constructor calls FunctionEffectsRef::get() in the case of an indirect call through a variable which has a Decl. So I think we're good.

Thanks for the quick review.

More patches? My favorite of Murphy's Laws of Programming is "if it is useful, it will have to be changed."

@cjappl
Copy link
Contributor

cjappl commented Oct 8, 2024

@dougsonos Maybe you should ask for commit access since you’ll likely be contributing more patches to this in the future as I understand it?

CC @AaronBallman Does that still work like it used to or did your maintainers rfc change something about that too?

A few days ago at least, the other RTSan coauthor followed the "old way" of emailing Chris Lattner to get access. He followed the same process I did a few months ago (email him asking for access with a list of commits you have contributed).

Not sure if that has changed in the last week or not.

jroelofs pushed a commit to swiftlang/llvm-project that referenced this pull request Oct 17, 2024
… when a and b are (llvm#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 <dwyatt@apple.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants