diff --git a/clang-tools-extra/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp index c0f76cc0267ba..c03af11b1bc4d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp @@ -23,12 +23,7 @@ static llvm::APFloat getHalf(const llvm::fltSemantics &Semantics) { namespace { AST_MATCHER(FloatingLiteral, floatHalf) { - const llvm::APFloat Literal = Node.getValue(); - if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle()) - return Literal == getHalf(llvm::APFloat::IEEEsingle()); - if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble()) - return Literal == getHalf(llvm::APFloat::IEEEdouble()); - return false; + return Node.getValue() == getHalf(Node.getSemantics()); } } // namespace @@ -39,24 +34,15 @@ void IncorrectRoundingsCheck::registerMatchers(MatchFinder *MatchFinder) { // Match a floating point expression. auto FloatType = expr(hasType(realFloatingPointType())); - // Match a floating literal of 0.5 or a floating literal of 0.5 implicitly. - // cast to floating type. - auto FloatOrCastHalf = - anyOf(FloatHalf, - implicitCastExpr(FloatType, has(ignoringParenImpCasts(FloatHalf)))); - - // Match if either the LHS or RHS is a floating literal of 0.5 or a floating - // literal of 0.5 and the other is of type double or vice versa. - auto OneSideHalf = anyOf(allOf(hasLHS(FloatOrCastHalf), hasRHS(FloatType)), - allOf(hasRHS(FloatOrCastHalf), hasLHS(FloatType))); - // Find expressions of cast to int of the sum of a floating point expression // and 0.5. MatchFinder->addMatcher( traverse(TK_AsIs, - implicitCastExpr(hasImplicitDestinationType(isInteger()), - ignoringParenCasts(binaryOperator( - hasOperatorName("+"), OneSideHalf))) + implicitCastExpr( + hasImplicitDestinationType(isInteger()), + ignoringParenCasts(binaryOperator( + hasOperatorName("+"), hasOperands(FloatType, FloatType), + hasEitherOperand(ignoringParenImpCasts(FloatHalf))))) .bind("CastExpr")), this); } diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 4563aa8de731c..d7359ec07fece 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -183,6 +183,10 @@ Changes in existing checks ` to handle iterators that do not define `value_type` type aliases. +- Improved :doc:`bugprone-incorrect-roundings + ` check by adding support for + other floating point representations in float constant like ``0.5L``. + - Deprecated check-local options `HeaderFileExtensions` and `ImplementationFileExtensions` in :doc:`bugprone-suspicious-include ` check. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-roundings.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-roundings.cpp index 7ada0616cc8b4..23bb0af015fd3 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-roundings.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/incorrect-roundings.cpp @@ -12,74 +12,126 @@ void f1() { // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) to integer leads to incorrect rounding; consider using lround (#include ) instead [bugprone-incorrect-roundings] x = (d + 0.5f); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) + x = (d + 0.5L); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) x = (f + 0.5); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) x = (f + 0.5f); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) + x = (f + 0.5L); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) x = (0.5 + d); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) x = (0.5f + d); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) + x = (0.5L + d); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) x = (0.5 + ld); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) x = (0.5f + ld); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) + x = (0.5L + ld); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) x = (0.5 + f); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) x = (0.5f + f); // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) + x = (0.5L + f); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: casting (double + 0.5) x = (int)(d + 0.5); // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) x = (int)(d + 0.5f); // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) + x = (int)(d + 0.5L); + // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) x = (int)(ld + 0.5); // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) x = (int)(ld + 0.5f); // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) + x = (int)(ld + 0.5L); + // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) x = (int)(f + 0.5); // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) x = (int)(f + 0.5f); // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) + x = (int)(f + 0.5L); + // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) x = (int)(0.5 + d); // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) x = (int)(0.5f + d); // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) + x = (int)(0.5L + d); + // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) x = (int)(0.5 + ld); // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) x = (int)(0.5f + ld); // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) + x = (int)(0.5L + ld); + // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) x = (int)(0.5 + f); // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) x = (int)(0.5f + f); // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) + x = (int)(0.5L + f); + // CHECK-MESSAGES: [[@LINE-1]]:12: warning: casting (double + 0.5) x = static_cast(d + 0.5); // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) x = static_cast(d + 0.5f); // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) + x = static_cast(d + 0.5L); + // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) x = static_cast(ld + 0.5); // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) x = static_cast(ld + 0.5f); // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) + x = static_cast(ld + 0.5L); + // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) x = static_cast(f + 0.5); // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) x = static_cast(f + 0.5f); // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) + x = static_cast(f + 0.5L); + // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) x = static_cast(0.5 + d); // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) x = static_cast(0.5f + d); // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) + x = static_cast(0.5L + d); + // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) x = static_cast(0.5 + ld); // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) x = static_cast(0.5f + ld); // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) + x = static_cast(0.5L + ld); + // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) x = static_cast(0.5 + f); // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) x = static_cast(0.5f + f); // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) + x = static_cast(0.5L + f); + // CHECK-MESSAGES: [[@LINE-1]]:24: warning: casting (double + 0.5) // Don't warn if constant is not 0.5. - x = (int)(d + 0.6); - x = (int)(0.6 + d); + x = (int)(d + 0.4999); + x = (int)(d + 0.4999f); + x = (int)(d + 0.4999L); + x = (int)(0.4999 + d); + x = (int)(0.4999f + d); + x = (int)(0.4999L + d); + + x = (int)(d + -0.5); + x = (int)(-0.5 + d); + x = (int)(d + -0.5f); + x = (int)(-0.5f + d); + x = (int)(d + -0.5L); + x = (int)(-0.5L + d); + + x = (int)(d + 0.5001); + x = (int)(d + 0.5001f); + x = (int)(d + 0.5001L); + x = (int)(0.5001 + d); + x = (int)(0.5001f + d); + x = (int)(0.5001L + d); // Don't warn if binary operator is not directly beneath cast. x = (int)(1 + (0.5 + f));