diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp --- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -304,7 +304,8 @@ ExplodedNodeSet dstPreStmt; getCheckerManager().runCheckersForPreStmt(dstPreStmt, Pred, CastE, *this); - if (CastE->getCastKind() == CK_LValueToRValue) { + if (CastE->getCastKind() == CK_LValueToRValue || + CastE->getCastKind() == CK_LValueToRValueBitCast) { for (ExplodedNodeSet::iterator I = dstPreStmt.begin(), E = dstPreStmt.end(); I!=E; ++I) { ExplodedNode *subExprNode = *I; @@ -332,6 +333,7 @@ switch (CastE->getCastKind()) { case CK_LValueToRValue: + case CK_LValueToRValueBitCast: llvm_unreachable("LValueToRValue casts handled earlier."); case CK_ToVoid: continue; @@ -380,7 +382,6 @@ case CK_Dependent: case CK_ArrayToPointerDecay: case CK_BitCast: - case CK_LValueToRValueBitCast: case CK_AddressSpaceConversion: case CK_BooleanToSignedIntegral: case CK_IntegralToPointer: diff --git a/clang/test/Analysis/builtin_bitcast.cpp b/clang/test/Analysis/builtin_bitcast.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/builtin_bitcast.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -verify %s \ +// RUN: -analyzer-checker=core,debug.ExprInspection + +template void clang_analyzer_dump(T); + +__attribute__((always_inline)) static inline constexpr unsigned int _castf32_u32(float __A) { + return __builtin_bit_cast(unsigned int, __A); // no-warning +} + +void test(int i) { + _castf32_u32(42); + + float f = 42; + + // Loading from a floating point value results in unknown, + // which later materializes as a conjured value. + auto g = __builtin_bit_cast(unsigned int, f); + clang_analyzer_dump(g); + // expected-warning-re@-1 {{{{^conj_\$[0-9]+{unsigned int,}}}} + + auto g2 = __builtin_bit_cast(unsigned int, 42.0f); + clang_analyzer_dump(g2); + // expected-warning-re@-1 {{{{^conj_\$[0-9]+{unsigned int,}}}} + + auto g3 = __builtin_bit_cast(unsigned int, i); + clang_analyzer_dump(g3); + // expected-warning-re@-1 {{{{^reg_\$[0-9]+}}}} + + auto g4 = __builtin_bit_cast(unsigned long, &i); + clang_analyzer_dump(g4); + // expected-warning@-1 {{&i [as 64 bit integer]}} +}