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