@@ -71,21 +71,30 @@ void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
7171 Bldr.takeNodes (Pred);
7272
7373 assert (ThisRD);
74- SVal V = Call.getArgSVal (0 );
75- const Expr *VExpr = Call.getArgExpr (0 );
7674
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 );
8378
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+ }
8998
9099 PostStmt PS (CallExpr, LCtx);
91100 for (ExplodedNode *N : Dst) {
0 commit comments