@@ -286,15 +286,47 @@ ProgramStateRef ExprEngine::handleLValueBitCast(
286
286
void ExprEngine::VisitCast (const CastExpr *CastE, const Expr *Ex,
287
287
ExplodedNode *Pred, ExplodedNodeSet &Dst) {
288
288
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);
298
330
}
299
331
return ;
300
332
}
@@ -306,8 +338,8 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
306
338
if (const ExplicitCastExpr *ExCast=dyn_cast_or_null<ExplicitCastExpr>(CastE))
307
339
T = ExCast->getTypeAsWritten ();
308
340
309
- StmtNodeBuilder Bldr (dstPreStmt , Dst, *currBldrCtx);
310
- for (ExplodedNode *Pred : dstPreStmt ) {
341
+ StmtNodeBuilder Bldr (DstPreStmt , Dst, *currBldrCtx);
342
+ for (ExplodedNode *Pred : DstPreStmt ) {
311
343
ProgramStateRef state = Pred->getState ();
312
344
const LocationContext *LCtx = Pred->getLocationContext ();
313
345
0 commit comments