Skip to content

Commit c72200d

Browse files
author
git apple-llvm automerger
committed
Merge commit '41229581a456' from llvm.org/main into next
2 parents b8b8a9f + 4122958 commit c72200d

File tree

3 files changed

+62
-15
lines changed

3 files changed

+62
-15
lines changed

clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -286,15 +286,47 @@ ProgramStateRef ExprEngine::handleLValueBitCast(
286286
void 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

clang/test/Analysis/builtin_bitcast.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -verify %s \
2-
// RUN: -analyzer-checker=core,debug.ExprInspection
2+
// RUN: -analyzer-checker=core,debug.ExprInspection -analyzer-disable-checker=core.FixedAddressDereference
33

44
template <typename T> void clang_analyzer_dump(T);
55
using size_t = decltype(sizeof(int));
@@ -39,7 +39,7 @@ struct A {
3939
}
4040
};
4141
void gh_69922(size_t p) {
42-
// expected-warning-re@+1 {{(reg_${{[0-9]+}}<size_t p>) & 1U}}
42+
// expected-warning@+1 {{Unknown}}
4343
clang_analyzer_dump(__builtin_bit_cast(A*, p & 1));
4444

4545
__builtin_bit_cast(A*, p & 1)->set(2); // no-crash
@@ -49,5 +49,20 @@ void gh_69922(size_t p) {
4949
// store to the member variable `n`.
5050

5151
clang_analyzer_dump(__builtin_bit_cast(A*, p & 1)->n); // Ideally, this should print "2".
52-
// expected-warning-re@-1 {{(reg_${{[0-9]+}}<size_t p>) & 1U}}
52+
// expected-warning@-1 {{Unknown}}
53+
}
54+
55+
namespace {
56+
typedef unsigned long uintptr_t;
57+
58+
bool previously_crash(const void *& ptr) {
59+
clang_analyzer_dump(__builtin_bit_cast(void*, static_cast<uintptr_t>(-1)));
60+
// expected-warning-re@-1 {{{{[0-9]+}} (Loc)}}
61+
return ptr == __builtin_bit_cast(void*, static_cast<uintptr_t>(-1));
62+
}
63+
64+
void check_loc_concreteInt() {
65+
clang_analyzer_dump(__builtin_bit_cast(unsigned, *(reinterpret_cast<int*>(0xdeadbeef))));
66+
// expected-warning@-1 {{Unknown}}
67+
}
5368
}

clang/test/Analysis/exercise-ps.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void f4(char *array) {
4141

4242
_Static_assert(sizeof(int) == 4, "Wrong triple for the test");
4343

44-
clang_analyzer_dump_int(__builtin_bit_cast(int, b)); // expected-warning {{lazyCompoundVal}}
44+
clang_analyzer_dump_int(__builtin_bit_cast(int, b)); // expected-warning {{Unknown}}
4545
clang_analyzer_dump_int(array[__builtin_bit_cast(int, b)]); // expected-warning {{Unknown}}
4646

4747
array[__builtin_bit_cast(int, b)] = 0x10; // no crash

0 commit comments

Comments
 (0)