From: Nick Desaulniers Date: Mon, 13 Aug 2018 16:38:07 +0000 (+0000) Subject: [SEMA] add more -Wfloat-conversion to compound assigment analysis X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=87be98223ce15a612013b6c44c725b714e62a35d;p=clang [SEMA] add more -Wfloat-conversion to compound assigment analysis Summary: Fixes Bug: https://bugs.llvm.org/show_bug.cgi?id=27061 Reviewers: aaron.ballman, acoomans Reviewed By: aaron.ballman, acoomans Subscribers: acoomans, cfe-commits, srhines, pirama Differential Revision: https://reviews.llvm.org/D50467 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@339581 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 71a6d069c0..7826446b79 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -10282,33 +10282,6 @@ static void DiagnoseImpCast(Sema &S, Expr *E, QualType T, DiagnoseImpCast(S, E, E->getType(), T, CContext, diag, pruneControlFlow); } -/// Analyze the given compound assignment for the possible losing of -/// floating-point precision. -static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E) { - assert(isa(E) && - "Must be compound assignment operation"); - // Recurse on the LHS and RHS in here - AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc()); - AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc()); - - // Now check the outermost expression - const auto *ResultBT = E->getLHS()->getType()->getAs(); - const auto *RBT = cast(E) - ->getComputationResultType() - ->getAs(); - - // If both source and target are floating points. - if (ResultBT && ResultBT->isFloatingPoint() && RBT && RBT->isFloatingPoint()) - // Builtin FP kinds are ordered by increasing FP rank. - if (ResultBT->getKind() < RBT->getKind()) - // We don't want to warn for system macro. - if (!S.SourceMgr.isInSystemMacro(E->getOperatorLoc())) - // warn about dropping FP rank. - DiagnoseImpCast(S, E->getRHS(), E->getLHS()->getType(), - E->getOperatorLoc(), - diag::warn_impcast_float_result_precision); -} - /// Diagnose an implicit cast from a floating point value to an integer value. static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T, SourceLocation CContext) { @@ -10411,6 +10384,39 @@ static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T, } } +/// Analyze the given compound assignment for the possible losing of +/// floating-point precision. +static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E) { + assert(isa(E) && + "Must be compound assignment operation"); + // Recurse on the LHS and RHS in here + AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc()); + AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc()); + + // Now check the outermost expression + const auto *ResultBT = E->getLHS()->getType()->getAs(); + const auto *RBT = cast(E) + ->getComputationResultType() + ->getAs(); + + // The below checks assume source is floating point. + if (!ResultBT || !RBT || !RBT->isFloatingPoint()) return; + + // If source is floating point but target is not. + if (!ResultBT->isFloatingPoint()) + return DiagnoseFloatingImpCast(S, E, E->getRHS()->getType(), + E->getExprLoc()); + + // If both source and target are floating points. + // Builtin FP kinds are ordered by increasing FP rank. + if (ResultBT->getKind() < RBT->getKind() && + // We don't want to warn for system macro. + !S.SourceMgr.isInSystemMacro(E->getOperatorLoc())) + // warn about dropping FP rank. + DiagnoseImpCast(S, E->getRHS(), E->getLHS()->getType(), E->getOperatorLoc(), + diag::warn_impcast_float_result_precision); +} + static std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range) { if (!Range.Width) return "0"; diff --git a/test/SemaCXX/warn-float-conversion.cpp b/test/SemaCXX/warn-float-conversion.cpp index a3d178622c..7dec4844b0 100644 --- a/test/SemaCXX/warn-float-conversion.cpp +++ b/test/SemaCXX/warn-float-conversion.cpp @@ -41,6 +41,32 @@ void Convert(float f, double d, long double ld) { l = ld; //expected-warning{{conversion}} } +void CompoundAssignment() { + int x = 3; + + x += 1.234; //expected-warning{{conversion}} + x -= -0.0; //expected-warning{{conversion}} + x *= 1.1f; //expected-warning{{conversion}} + x /= -2.2f; //expected-warning{{conversion}} + + int y = x += 1.4f; //expected-warning{{conversion}} + + float z = 1.1f; + double w = -2.2; + + y += z + w; //expected-warning{{conversion}} +} + +# 1 "foo.h" 3 +// ^ the following text comes from a system header file. +#define SYSTEM_MACRO_FLOAT(x) do { (x) += 1.1; } while(0) +# 1 "warn-float-conversion.cpp" 1 +// ^ start of a new file. +void SystemMacro() { + float x = 0.0f; + SYSTEM_MACRO_FLOAT(x); +} + void Test() { int a1 = 10.0/2.0; //expected-warning{{conversion}} int a2 = 1.0/2.0; //expected-warning{{conversion}}