[clang] 0dfae06 - [analyzer] Trigger copy event when copying empty structs (3/4) (#115918)

via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 15 01:55:25 PST 2024


Author: Balazs Benics
Date: 2024-11-15T10:55:22+01:00
New Revision: 0dfae0676014ca961fa404fd40d609f58d935b63

URL: https://github.com/llvm/llvm-project/commit/0dfae0676014ca961fa404fd40d609f58d935b63
DIFF: https://github.com/llvm/llvm-project/commit/0dfae0676014ca961fa404fd40d609f58d935b63.diff

LOG: [analyzer] Trigger copy event when copying empty structs (3/4) (#115918)

Previously, ExprEngine would just skip copying empty structs.
Let's make trigger the copy event even for empty structs.

Split from #114835

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index ccc3097e8d2f97..17ee1f7c945edd 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -68,23 +68,15 @@ void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
   Bldr.takeNodes(Pred);
 
   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);
-
-    // 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);
-  }
+  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());
+  evalBind(Dst, CallExpr, Pred, ThisVal, V, true);
 
   PostStmt PS(CallExpr, LCtx);
   for (ExplodedNode *N : Dst) {

diff  --git a/clang/test/Analysis/ctor-trivial-copy.cpp b/clang/test/Analysis/ctor-trivial-copy.cpp
index ab623c1919e152..41d0d97161bba1 100644
--- a/clang/test/Analysis/ctor-trivial-copy.cpp
+++ b/clang/test/Analysis/ctor-trivial-copy.cpp
@@ -51,11 +51,7 @@ void _01_empty_structs() {
   clang_analyzer_dump_val(Empty2); // expected-warning {{lazyCompoundVal}}
   clang_analyzer_dump_val(Empty3); // expected-warning {{lazyCompoundVal}}
 
-  // Notice that we don't have entries for the copies, only for the original "Empty" object.
-  // That binding was added by the opaque "conjure" call, directly constructing to the variable "Empty" by copy-elision.
-  // The copies are not present because the ExprEngine skips the evalBind of empty structs.
-  // And even if such binds would reach the Store, the Store copies small structs by copying the individual fields,
-  // and there are no fields within "Empty", thus we wouldn't have any entries anyways.
+  // We should have the same Conjured symbol for "Empty", "Empty2" and "Empty3".
   clang_analyzer_printState();
   // CHECK:       "store": { "pointer": "0x{{[0-9a-f]+}}", "items": [
   // CHECK-NEXT:    { "cluster": "GlobalInternalSpaceRegion", "pointer": "0x{{[0-9a-f]+}}", "items": [
@@ -66,6 +62,12 @@ void _01_empty_structs() {
   // CHECK-NEXT:    ]},
   // CHECK-NEXT:    { "cluster": "Empty", "pointer": "0x{{[0-9a-f]+}}", "items": [
   // CHECK-NEXT:      { "kind": "Default", "offset": 0, "value": "[[EMPTY_CONJ:conj_\$[0-9]+{int, LC[0-9]+, S[0-9]+, #[0-9]+}]]" }
+  // CHECK-NEXT:    ]},
+  // CHECK-NEXT:    { "cluster": "Empty2", "pointer": "0x{{[0-9a-f]+}}", "items": [
+  // CHECK-NEXT:      { "kind": "Default", "offset": 0, "value": "[[EMPTY_CONJ]]" }
+  // CHECK-NEXT:    ]},
+  // CHECK-NEXT:    { "cluster": "Empty3", "pointer": "0x{{[0-9a-f]+}}", "items": [
+  // CHECK-NEXT:      { "kind": "Default", "offset": 0, "value": "[[EMPTY_CONJ]]" }
   // CHECK-NEXT:    ]}
   // CHECK-NEXT:  ]},
 


        


More information about the cfe-commits mailing list