Index: clang/lib/StaticAnalyzer/Core/SValBuilder.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ clang/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -501,8 +501,13 @@ if (getContext().getTypeSize(castTy) >= getContext().getTypeSize(originalTy)) return evalCast(val, castTy, originalTy); + // The code call below would convert the int into a float. + // What we want, however, is a bit-by-bit reinterpretation of the int + // as a float, which usually yields nothing garbage. + // TODO: What other combinations of types are affected? + // Let evalCast handle non symbolic expressions and float symbols. SymbolRef se = val.getAsSymbol(); - if (!se) // Let evalCast handle non symbolic expressions. + if (!se || se->getType()->isFloatingType()) return evalCast(val, castTy, originalTy); // Find the maximum value of the target type. Index: clang/lib/StaticAnalyzer/Core/Store.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/Store.cpp +++ clang/lib/StaticAnalyzer/Core/Store.cpp @@ -407,17 +407,6 @@ if (castTy.isNull() || V.isUnknownOrUndef()) return V; - // The dispatchCast() call below would convert the int into a float. - // What we want, however, is a bit-by-bit reinterpretation of the int - // as a float, which usually yields nothing garbage. For now skip casts - // from ints to floats. - // TODO: What other combinations of types are affected? - if (castTy->isFloatingType()) { - SymbolRef Sym = V.getAsSymbol(); - if (Sym && !Sym->getType()->isFloatingType()) - return UnknownVal(); - } - // When retrieving symbolic pointer and expecting a non-void pointer, // wrap them into element regions of the expected type if necessary. // SValBuilder::dispatchCast() doesn't do that, but it is necessary to Index: clang/test/Analysis/svalbuilder-float-cast.c =================================================================== --- clang/test/Analysis/svalbuilder-float-cast.c +++ clang/test/Analysis/svalbuilder-float-cast.c @@ -4,17 +4,23 @@ void SymbolCast_of_float_type_aux(int *p) { *p += 0; - // FIXME: Ideally, all unknown values should be symbolicated. - clang_analyzer_denote(*p, "$x"); // expected-warning{{Not a symbol}} + clang_analyzer_denote(*p, "$x"); *p += 1; - // This should NOT be (float)$x + 1. Symbol $x was never casted to float. - // FIXME: Ideally, this should be $x + 1. - clang_analyzer_express(*p); // expected-warning{{Not a symbol}} + // expected-warning@+3{{(float)$x + 1}} + // expected-warning@+2{{(double)$x + 1}} + // expected-warning@+1{{(long double)$x + 1}} + clang_analyzer_express(*p); } void SymbolCast_of_float_type() { - extern float x; + extern float x1; + extern double x2; + extern long double x3; + void (*f)() = SymbolCast_of_float_type_aux; - f(&x); + + f(&x1); + f(&x2); + f(&x3); }