@@ -71,21 +71,30 @@ void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
71
71
Bldr.takeNodes (Pred);
72
72
73
73
assert (ThisRD);
74
- SVal V = Call.getArgSVal (0 );
75
- const Expr *VExpr = Call.getArgExpr (0 );
76
74
77
- // If the value being copied is not unknown, load from its location to get
78
- // an aggregate rvalue.
79
- if (std::optional<Loc> L = V.getAs <Loc>())
80
- V = Pred->getState ()->getSVal (*L);
81
- else
82
- assert (V.isUnknownOrUndef ());
75
+ if (!ThisRD->isEmpty ()) {
76
+ SVal V = Call.getArgSVal (0 );
77
+ const Expr *VExpr = Call.getArgExpr (0 );
83
78
84
- ExplodedNodeSet Tmp;
85
- evalLocation (Tmp, CallExpr, VExpr, Pred, Pred->getState (), V,
86
- /* isLoad=*/ true );
87
- for (ExplodedNode *N : Tmp)
88
- evalBind (Dst, CallExpr, N, ThisVal, V, true );
79
+ // If the value being copied is not unknown, load from its location to get
80
+ // an aggregate rvalue.
81
+ if (std::optional<Loc> L = V.getAs <Loc>())
82
+ V = Pred->getState ()->getSVal (*L);
83
+ else
84
+ assert (V.isUnknownOrUndef ());
85
+
86
+ ExplodedNodeSet Tmp;
87
+ evalLocation (Tmp, CallExpr, VExpr, Pred, Pred->getState (), V,
88
+ /* isLoad=*/ true );
89
+ for (ExplodedNode *N : Tmp)
90
+ evalBind (Dst, CallExpr, N, ThisVal, V, true );
91
+ } else {
92
+ // We can't copy empty classes because of empty base class optimization.
93
+ // In that case, copying the empty base class subobject would overwrite the
94
+ // object that it overlaps with - so let's not do that.
95
+ // See issue-157467.cpp for an example.
96
+ Dst.Add (Pred);
97
+ }
89
98
90
99
PostStmt PS (CallExpr, LCtx);
91
100
for (ExplodedNode *N : Dst) {
0 commit comments