@@ -286,15 +286,47 @@ ProgramStateRef ExprEngine::handleLValueBitCast(
286286void ExprEngine::VisitCast (const CastExpr *CastE, const Expr *Ex,
287287 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
288288
289- ExplodedNodeSet dstPreStmt;
290- getCheckerManager ().runCheckersForPreStmt (dstPreStmt, Pred, CastE, *this );
291-
292- if (CastE->getCastKind () == CK_LValueToRValue ||
293- CastE->getCastKind () == CK_LValueToRValueBitCast) {
294- for (ExplodedNode *subExprNode : dstPreStmt) {
295- ProgramStateRef state = subExprNode->getState ();
296- const LocationContext *LCtx = subExprNode->getLocationContext ();
297- evalLoad (Dst, CastE, CastE, subExprNode, state, state->getSVal (Ex, LCtx));
289+ ExplodedNodeSet DstPreStmt;
290+ getCheckerManager ().runCheckersForPreStmt (DstPreStmt, Pred, CastE, *this );
291+
292+ if (CastE->getCastKind () == CK_LValueToRValue) {
293+ for (ExplodedNode *Node : DstPreStmt) {
294+ ProgramStateRef State = Node->getState ();
295+ const LocationContext *LCtx = Node->getLocationContext ();
296+ evalLoad (Dst, CastE, CastE, Node, State, State->getSVal (Ex, LCtx));
297+ }
298+ return ;
299+ }
300+ if (CastE->getCastKind () == CK_LValueToRValueBitCast) {
301+ // Handle `__builtin_bit_cast`:
302+ ExplodedNodeSet DstEvalLoc;
303+
304+ // Simulate the lvalue-to-rvalue conversion on `Ex`:
305+ for (ExplodedNode *Node : DstPreStmt) {
306+ ProgramStateRef State = Node->getState ();
307+ const LocationContext *LCtx = Node->getLocationContext ();
308+ evalLocation (DstEvalLoc, CastE, Ex, Node, State, State->getSVal (Ex, LCtx),
309+ true );
310+ }
311+ // Simulate the operation that actually casts the original value to a new
312+ // value of the destination type :
313+ StmtNodeBuilder Bldr (DstEvalLoc, Dst, *currBldrCtx);
314+
315+ for (ExplodedNode *Node : DstEvalLoc) {
316+ ProgramStateRef State = Node->getState ();
317+ const LocationContext *LCtx = Node->getLocationContext ();
318+ // Although `Ex` is an lvalue, it could have `Loc::ConcreteInt` kind
319+ // (e.g., `(int *)123456`). In such cases, there is no MemRegion
320+ // available and we can't get the value to be casted.
321+ SVal CastedV = UnknownVal ();
322+
323+ if (const MemRegion *MR = State->getSVal (Ex, LCtx).getAsRegion ()) {
324+ SVal OrigV = State->getSVal (MR);
325+ CastedV = svalBuilder.evalCast (svalBuilder.simplifySVal (State, OrigV),
326+ CastE->getType (), Ex->getType ());
327+ }
328+ State = State->BindExpr (CastE, LCtx, CastedV);
329+ Bldr.generateNode (CastE, Node, State);
298330 }
299331 return ;
300332 }
@@ -306,8 +338,8 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
306338 if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
307339 T = ExCast->getTypeAsWritten ();
308340
309- StmtNodeBuilder Bldr (dstPreStmt , Dst, *currBldrCtx);
310- for (ExplodedNode *Pred : dstPreStmt ) {
341+ StmtNodeBuilder Bldr (DstPreStmt , Dst, *currBldrCtx);
342+ for (ExplodedNode *Pred : DstPreStmt ) {
311343 ProgramStateRef state = Pred->getState ();
312344 const LocationContext *LCtx = Pred->getLocationContext ();
313345
0 commit comments