xbolva00 updated this revision to Diff 168150. xbolva00 added a comment. - better warning
https://reviews.llvm.org/D52835 Files: lib/Sema/SemaChecking.cpp test/Sema/ext_vector_casts.c test/Sema/impcast-integer-float.c
Index: test/Sema/impcast-integer-float.c =================================================================== --- test/Sema/impcast-integer-float.c +++ test/Sema/impcast-integer-float.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %s -verify -Wconversion -fsyntax-only + +#define shift_plus_one(x) ((1ULL << x) + 1) + +void test(void) { + float a1 = (1ULL << 31) + 1; // expected-warning {{implicit conversion from 'unsigned long long' to 'float' changes value from 2147483649 to 2.147484E+9}} + float a2 = 1ULL << 31; + float a3 = shift_plus_one(31); // expected-warning {{implicit conversion from 'unsigned long long' to 'float' changes value from 2147483649 to 2.147484E+9}} + float a4 = (1ULL << 31) - 1; // expected-warning {{implicit conversion from 'unsigned long long' to 'float' changes value from 2147483647 to 2.147483E+9}} + + double b1 = (1ULL << 63) + 1; // expected-warning {{implicit conversion from 'unsigned long long' to 'double' changes value from 9223372036854775809 to 9.223372036854775E+18}} + double b2 = 1ULL << 63; + double b3 = shift_plus_one(63); // expected-warning {{implicit conversion from 'unsigned long long' to 'double' changes value from 9223372036854775809 to 9.223372036854775E+18}} + double b4 = (1ULL << 63) - 1; // expected-warning {{implicit conversion from 'unsigned long long' to 'double' changes value from 9223372036854775807 to 9.223372036854775E+18}} +} Index: test/Sema/ext_vector_casts.c =================================================================== --- test/Sema/ext_vector_casts.c +++ test/Sema/ext_vector_casts.c @@ -118,7 +118,7 @@ vf = l + vf; vf = 2.0 + vf; vf = d + vf; // expected-warning {{implicit conversion loses floating-point precision}} - vf = vf + 0xffffffff; + vf = vf + 0xffffffff; // expected-warning {{implicit conversion from 'unsigned int' to 'float2' (vector of 2 'float' values) changes value from 4294967295 to 4.294967E+9}} vf = vf + 2.1; // expected-warning {{implicit conversion loses floating-point precision}} vd = l + vd; Index: lib/Sema/SemaChecking.cpp =================================================================== --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -105,6 +105,12 @@ Context.getTargetInfo()); } +/// Force the precision of the source value down so we don't print digits which +/// are usually useless +static unsigned AdjustPrecision(unsigned precision) { + return (precision * 59 + 195) / 196; +} + /// Checks that a call expression's argument count is the desired number. /// This is useful when doing custom type-checking. Returns true on error. static bool checkArgCount(Sema &S, CallExpr *call, unsigned desiredArgCount) { @@ -10418,7 +10424,7 @@ // tricky to implement. SmallString<16> PrettySourceValue; unsigned precision = llvm::APFloat::semanticsPrecision(Value.getSemantics()); - precision = (precision * 59 + 195) / 196; + precision = AdjustPrecision(precision); Value.toString(PrettySourceValue, precision); SmallString<16> PrettyTargetValue; @@ -10852,6 +10858,42 @@ return; } + if (Source->isIntegerType() && Target->isFloatingType()) { + const llvm::fltSemantics *FloatSem = nullptr; + if (Target->isSpecificBuiltinType(BuiltinType::Float)) { + FloatSem = &llvm::APFloat::IEEEsingle(); + } else if (Target->isSpecificBuiltinType(BuiltinType::Double)) { + FloatSem = &llvm::APFloat::IEEEdouble(); + } + + if (FloatSem) { + llvm::APFloat FloatValue(*FloatSem); + llvm::APSInt IntValue; + if (E->EvaluateAsInt(IntValue, S.Context, Expr::SE_AllowSideEffects)) { + if (S.SourceMgr.isInSystemMacro(CC)) + return; + + if (FloatValue.convertFromAPInt(IntValue, Source->isSignedIntegerType(), + llvm::APFloat::rmTowardZero) != + llvm::APFloat::opOK) { + SmallString<16> PrettyTargetValue; + SmallString<16> PrettySourceValue; + unsigned precision = llvm::APFloat::semanticsPrecision(*FloatSem); + precision = AdjustPrecision(precision); + FloatValue.toString(PrettyTargetValue, precision); + IntValue.toString(PrettySourceValue); + + S.DiagRuntimeBehavior( + E->getExprLoc(), E, + S.PDiag(diag::warn_impcast_literal_float_to_integer) + << E->getType() << T << PrettySourceValue << PrettyTargetValue + << E->getSourceRange() << clang::SourceRange(CC)); + return; + } + } + } + } + DiagnoseNullConversion(S, E, T, CC); S.DiscardMisalignedMemberAddress(Target, E);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits