llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-static-analyzer-1

Author: None (flovent)

<details>
<summary>Changes</summary>

For lambdas that are converted to C function pointers, 
```
int (*ret_zero)() = []() { return 0; };
```
clang will generate conversion method like:
```
CXXConversionDecl implicit used constexpr operator int (*)() 'int (*() const 
noexcept)()' inline
 -CompoundStmt
   -ReturnStmt
    -ImplicitCastExpr 'int (*)()' &lt;FunctionToPointerDecay&gt;
     -DeclRefExpr 'int ()' lvalue CXXMethod 0x5ddb6fe35b18 '__invoke' 'int ()'
-CXXMethodDecl implicit used __invoke 'int ()' static inline
 -CompoundStmt (empty)
```
Based on comment in Sema, `__invoke`'s function body is left empty because it's 
will be filled in CodeGen, so in AST analysis phase we should get lambda's 
`operator()` directly instead of calling `__invoke` itself.

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


3 Files Affected:

- (modified) clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h 
(+2) 
- (modified) clang/lib/StaticAnalyzer/Core/CallEvent.cpp (+12) 
- (added) clang/test/Analysis/lambda-convert-to-func-ptr.cpp (+21) 


``````````diff
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h 
b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index f6a43bf5f493b..5dcf03f7a4648 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -554,6 +554,8 @@ class SimpleFunctionCall : public AnyFunctionCall {
 
   const FunctionDecl *getDecl() const override;
 
+  RuntimeDefinition getRuntimeDefinition() const override;
+
   unsigned getNumArgs() const override { return getOriginExpr()->getNumArgs(); 
}
 
   const Expr *getArgExpr(unsigned Index) const override {
diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp 
b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
index f78b1b84f9df6..34fcb9b64d555 100644
--- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -688,6 +688,18 @@ const FunctionDecl *SimpleFunctionCall::getDecl() const {
   return getSVal(getOriginExpr()->getCallee()).getAsFunctionDecl();
 }
 
+RuntimeDefinition SimpleFunctionCall::getRuntimeDefinition() const {
+  // Clang converts lambdas to function pointers using an implicit conversion
+  // operator, which returns the lambda's '__invoke' method. However, Sema
+  // leaves the body of '__invoke' empty (it is generated later in CodeGen), so
+  // we need to skip '__invoke' and access the lambda's operator() directly.
+  if (const auto *CMD = dyn_cast_if_present<CXXMethodDecl>(getDecl());
+      CMD && CMD->isLambdaStaticInvoker())
+    return RuntimeDefinition{CMD->getParent()->getLambdaCallOperator()};
+
+  return AnyFunctionCall::getRuntimeDefinition();
+}
+
 const FunctionDecl *CXXInstanceCall::getDecl() const {
   const auto *CE = cast_or_null<CallExpr>(getOriginExpr());
   if (!CE)
diff --git a/clang/test/Analysis/lambda-convert-to-func-ptr.cpp 
b/clang/test/Analysis/lambda-convert-to-func-ptr.cpp
new file mode 100644
index 0000000000000..c2ad7cd2de34a
--- /dev/null
+++ b/clang/test/Analysis/lambda-convert-to-func-ptr.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_analyze_cc1 -std=c++11 
-analyzer-checker=core,debug.ExprInspection -analyzer-config 
inline-lambdas=true -verify %s
+
+void clang_analyzer_eval(bool);
+
+void basic() {
+  int (*ret_zero)() = []() { return 0; };
+  clang_analyzer_eval(ret_zero() == 0); // expected-warning{{TRUE}}
+}
+
+void withParam() {
+  int (*add_ten)(int) = [](int b) { return b + 10; };
+  clang_analyzer_eval(add_ten(1) == 11); // expected-warning{{TRUE}}
+}
+
+int callBack(int (*fp)(int), int x) {
+  return fp(x);
+}
+
+void passWithFunc() {
+  clang_analyzer_eval(callBack([](int x) { return x; }, 5) == 5); // 
expected-warning{{TRUE}}
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/144906
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to