@@ -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