summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorZiang Wan <ziangw2@illinois.edu>2019-07-25 00:32:50 +0000
committerZiang Wan <ziangw2@illinois.edu>2019-07-25 00:32:50 +0000
commit2028d97d09b8abb7f47c4ad4ed6ffe7a1f6486ea (patch)
treec312b19bf7b42e736d4a24db44cb413932b7254e /clang/lib/Sema/SemaChecking.cpp
parent5aee1c6b102fcc4890a5fa73e320f850328024b3 (diff)
downloadbcm5719-llvm-2028d97d09b8abb7f47c4ad4ed6ffe7a1f6486ea.tar.gz
bcm5719-llvm-2028d97d09b8abb7f47c4ad4ed6ffe7a1f6486ea.zip
[Sema] Enable -Wimplicit-float-conversion for integral to floating point precision loss
Issue an warning when the code tries to do an implicit int -> float conversion, where the float type ha a narrower significant than the float type. The new warning is controlled by flag -Wimplicit-int-float-conversion, under -Wimplicit-float-conversion and -Wconversion. Differential Revision: https://reviews.llvm.org/D64666 llvm-svn: 366972
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index f9f82cdeef4..2b0d8c903b4 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -11400,6 +11400,55 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC,
}
}
+ // If we are casting an integer type to a floating point type, we might
+ // lose accuracy if the floating point type has a narrower significand
+ // than the integer type. Issue warnings for that accuracy loss.
+ if (SourceBT && TargetBT && SourceBT->isIntegerType() &&
+ TargetBT->isFloatingType()) {
+ // Determine the number of precision bits in the source integer type.
+ IntRange SourceRange = GetExprRange(S.Context, E, S.isConstantEvaluated());
+ unsigned int SourcePrecision = SourceRange.Width;
+
+ // Determine the number of precision bits in the
+ // target floating point type.
+ unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
+ S.Context.getFloatTypeSemantics(QualType(TargetBT, 0)));
+
+ if (SourcePrecision > 0 && TargetPrecision > 0 &&
+ SourcePrecision > TargetPrecision) {
+
+ llvm::APSInt SourceInt;
+ if (E->isIntegerConstantExpr(SourceInt, S.Context)) {
+ // If the source integer is a constant, convert it to the target
+ // floating point type. Issue a warning if the value changes
+ // during the whole conversion.
+ llvm::APFloat TargetFloatValue(
+ S.Context.getFloatTypeSemantics(QualType(TargetBT, 0)));
+ llvm::APFloat::opStatus ConversionStatus =
+ TargetFloatValue.convertFromAPInt(SourceInt,
+ SourceBT->isSignedInteger(), llvm::APFloat::rmNearestTiesToEven);
+
+ if (ConversionStatus != llvm::APFloat::opOK) {
+ std::string PrettySourceValue = SourceInt.toString(10);
+ SmallString<32> PrettyTargetValue;
+ TargetFloatValue.toString(PrettyTargetValue,
+ TargetPrecision);
+
+ S.DiagRuntimeBehavior(
+ E->getExprLoc(), E,
+ S.PDiag(diag::warn_impcast_integer_float_precision_constant)
+ << PrettySourceValue << PrettyTargetValue
+ << E->getType() << T
+ << E->getSourceRange() << clang::SourceRange(CC));
+ }
+ } else {
+ // Otherwise, the implicit conversion may lose precision.
+ DiagnoseImpCast(S, E, T, CC,
+ diag::warn_impcast_integer_float_precision);
+ }
+ }
+ }
+
DiagnoseNullConversion(S, E, T, CC);
S.DiscardMisalignedMemberAddress(Target, E);
OpenPOWER on IntegriCloud