[clang] 9d2e830 - [analyzer] Fix BindingDecl evaluation for reference types

via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 29 04:01:42 PDT 2022


Author: isuckatcs
Date: 2022-06-29T13:01:19+02:00
New Revision: 9d2e830737bcf8035cf263e4b4cb279b7b07cf24

URL: https://github.com/llvm/llvm-project/commit/9d2e830737bcf8035cf263e4b4cb279b7b07cf24
DIFF: https://github.com/llvm/llvm-project/commit/9d2e830737bcf8035cf263e4b4cb279b7b07cf24.diff

LOG: [analyzer] Fix BindingDecl evaluation for reference types

The case when the bound variable is reference type in a
BindingDecl wasn't handled, which lead to false positives.

Differential Revision: https://reviews.llvm.org/D128716

Added: 
    

Modified: 
    clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
    clang/test/Analysis/structured_bindings.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 1d99236a50379..b03d02640a87b 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -2630,6 +2630,9 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D,
     } else
       llvm_unreachable("An unknown case of structured binding encountered!");
 
+    if (BD->getType()->isReferenceType())
+      V = state->getSVal(V.getAsRegion());
+
     Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), nullptr,
                       ProgramPoint::PostLValueKind);
 

diff  --git a/clang/test/Analysis/structured_bindings.cpp b/clang/test/Analysis/structured_bindings.cpp
index 3e8ff1c2aa6ab..7004c2e7dcf43 100644
--- a/clang/test/Analysis/structured_bindings.cpp
+++ b/clang/test/Analysis/structured_bindings.cpp
@@ -1,9 +1,32 @@
-// RUN: %clang_analyze_cc1 -std=c++17 -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -std=c++17 -analyzer-checker=core,debug.ExprInspection -verify %s
+
+void clang_analyzer_eval(bool);
 
 struct s { int a; };
 int foo() {
-    auto[a] = s{1}; // FIXME: proper modelling
-    if (a) {
-    }
+  auto [a] = s{1};
+  clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
 } // expected-warning{{non-void function does not return a value}}
 
+struct s2 {
+  int &x;
+};
+
+int *foo2(s2 in) {
+  auto [a] = in;
+  return &a;
+}
+
+void bar() {
+  int i = 1;
+  s2 a{i};
+
+  auto *x = foo2(a);
+
+  clang_analyzer_eval(*x == i); // expected-warning{{TRUE}}
+
+  *x = 2;
+
+  clang_analyzer_eval(*x == 2); // expected-warning{{TRUE}}
+  clang_analyzer_eval(i == 2);  // expected-warning{{TRUE}}
+}


        


More information about the cfe-commits mailing list