[PATCH] D155442: [analyzer] Bind return value for assigment and copies of trivial empty classes

Tomasz KamiƄski via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 17 23:46:43 PDT 2023


This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG61760bb98c46: [analyzer] Bind return value for assigment and copies of trivial empty classes (authored by tomasz-kaminski-sonarsource).

Changed prior to commit:
  https://reviews.llvm.org/D155442?vs=540952&id=541336#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155442/new/

https://reviews.llvm.org/D155442

Files:
  clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  clang/test/Analysis/ctor-trivial-copy.cpp


Index: clang/test/Analysis/ctor-trivial-copy.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/ctor-trivial-copy.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=constructors -verify %s
+
+
+template<typename T>
+void clang_analyzer_dump(T&);
+
+struct aggr {
+  int x;
+  int y;
+};
+
+struct empty {
+};
+
+void test_copy_return() {
+  aggr s1 = {1, 2};
+  aggr const& cr1 = aggr(s1);
+  clang_analyzer_dump(cr1); // expected-warning-re {{&lifetime_extended_object{aggr, cr1, S{{[0-9]+}}} }}
+
+  empty s2;
+  empty const& cr2 = empty{s2};
+  clang_analyzer_dump(cr2); // expected-warning-re {{&lifetime_extended_object{empty, cr2, S{{[0-9]+}}} }}
+}
+
+void test_assign_return() {
+  aggr s1 = {1, 2};
+  aggr d1;
+  clang_analyzer_dump(d1 = s1); // expected-warning {{&d1 }}
+
+  empty s2;
+  empty d2;
+  clang_analyzer_dump(d2 = s2); // expected-warning {{&d2 }} was Unknown
+}
+
Index: clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -61,30 +61,30 @@
     AlwaysReturnsLValue = true;
   }
 
-  assert(ThisRD);
-  if (ThisRD->isEmpty()) {
-    // Do nothing for empty classes. Otherwise it'd retrieve an UnknownVal
-    // and bind it and RegionStore would think that the actual value
-    // in this region at this offset is unknown.
-    return;
-  }
-
   const LocationContext *LCtx = Pred->getLocationContext();
+  const Expr *CallExpr = Call.getOriginExpr();
 
   ExplodedNodeSet Dst;
   Bldr.takeNodes(Pred);
 
-  SVal V = Call.getArgSVal(0);
-
-  // If the value being copied is not unknown, load from its location to get
-  // an aggregate rvalue.
-  if (std::optional<Loc> L = V.getAs<Loc>())
-    V = Pred->getState()->getSVal(*L);
-  else
-    assert(V.isUnknownOrUndef());
+  assert(ThisRD);
+  if (!ThisRD->isEmpty()) {
+    // Load the source value only for non-empty classes.
+    // Otherwise it'd retrieve an UnknownVal
+    // and bind it and RegionStore would think that the actual value
+    // in this region at this offset is unknown.
+    SVal V = Call.getArgSVal(0);
 
-  const Expr *CallExpr = Call.getOriginExpr();
-  evalBind(Dst, CallExpr, Pred, ThisVal, V, true);
+    // If the value being copied is not unknown, load from its location to get
+    // an aggregate rvalue.
+    if (std::optional<Loc> L = V.getAs<Loc>())
+      V = Pred->getState()->getSVal(*L);
+    else
+      assert(V.isUnknownOrUndef());
+    evalBind(Dst, CallExpr, Pred, ThisVal, V, true);
+  } else {
+    Dst.Add(Pred);
+  }
 
   PostStmt PS(CallExpr, LCtx);
   for (ExplodedNode *N : Dst) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D155442.541336.patch
Type: text/x-patch
Size: 2812 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230718/79cc6ddd/attachment-0001.bin>


More information about the cfe-commits mailing list