Author: Amr Hesham Date: 2025-01-20T22:21:48+01:00 New Revision: e5992b686bb06dd53a4ff1e9586fa350d3ff43b5
URL: https://github.com/llvm/llvm-project/commit/e5992b686bb06dd53a4ff1e9586fa350d3ff43b5 DIFF: https://github.com/llvm/llvm-project/commit/e5992b686bb06dd53a4ff1e9586fa350d3ff43b5.diff LOG: [Clang] Fix warning for non std functions with name `infinity` (#123417) Fix reporting diagnostic for non std functions that has the name `infinity` Fixes: #123231 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaChecking.cpp clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp clang/test/Sema/warn-infinity-nan-disabled-win.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f6d5c346021d60..d7456082e32d00 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -798,6 +798,8 @@ Improvements to Clang's diagnostics } - Diagnose invalid declarators in the declaration of constructors and destructors (#GH121706). +- Fix false positives warning for non-std functions with name `infinity` (#123231). + Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 881907ac311a30..c41164a2f1af1c 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -8454,26 +8454,43 @@ static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check) { llvm_unreachable("unknown MathCheck"); } +static bool IsInfinityFunction(const FunctionDecl *FDecl) { + if (FDecl->getName() != "infinity") + return false; + + if (const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) { + const CXXRecordDecl *RDecl = MDecl->getParent(); + if (RDecl->getName() != "numeric_limits") + return false; + + if (const NamespaceDecl *NSDecl = + dyn_cast<NamespaceDecl>(RDecl->getDeclContext())) + return NSDecl->isStdNamespace(); + } + + return false; +} + void Sema::CheckInfNaNFunction(const CallExpr *Call, const FunctionDecl *FDecl) { + if (!FDecl->getIdentifier()) + return; + FPOptions FPO = Call->getFPFeaturesInEffect(getLangOpts()); - bool HasIdentifier = FDecl->getIdentifier() != nullptr; - bool IsNaNOrIsUnordered = - IsStdFunction(FDecl, "isnan") || IsStdFunction(FDecl, "isunordered"); - bool IsSpecialNaN = - HasIdentifier && IsInfOrNanFunction(FDecl->getName(), MathCheck::NaN); - if ((IsNaNOrIsUnordered || IsSpecialNaN) && FPO.getNoHonorNaNs()) { + if (FPO.getNoHonorNaNs() && + (IsStdFunction(FDecl, "isnan") || IsStdFunction(FDecl, "isunordered") || + IsInfOrNanFunction(FDecl->getName(), MathCheck::NaN))) { Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) << 1 << 0 << Call->getSourceRange(); - } else { - bool IsInfOrIsFinite = - IsStdFunction(FDecl, "isinf") || IsStdFunction(FDecl, "isfinite"); - bool IsInfinityOrIsSpecialInf = - HasIdentifier && ((FDecl->getName() == "infinity") || - IsInfOrNanFunction(FDecl->getName(), MathCheck::Inf)); - if ((IsInfOrIsFinite || IsInfinityOrIsSpecialInf) && FPO.getNoHonorInfs()) - Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) - << 0 << 0 << Call->getSourceRange(); + return; + } + + if (FPO.getNoHonorInfs() && + (IsStdFunction(FDecl, "isinf") || IsStdFunction(FDecl, "isfinite") || + IsInfinityFunction(FDecl) || + IsInfOrNanFunction(FDecl->getName(), MathCheck::Inf))) { + Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) + << 0 << 0 << Call->getSourceRange(); } } diff --git a/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp b/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp index 357c9e5b641073..4f46b777c88742 100644 --- a/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp +++ b/clang/test/Sema/warn-infinity-nan-disabled-lnx.cpp @@ -45,24 +45,48 @@ namespace std __attribute__((__visibility__("default"))) { isnan(double __x); bool isnan(long double __x); -bool + bool isfinite(float __x); bool isfinite(double __x); bool isfinte(long double __x); - bool + bool isunordered(float __x, float __y); bool isunordered(double __x, double __y); bool isunordered(long double __x, long double __y); + +template <class _Ty> +class numeric_limits { +public: + [[nodiscard]] static constexpr _Ty infinity() noexcept { + return _Ty(); + } +}; } // namespace ) } #define NAN (__builtin_nanf("")) #define INFINITY (__builtin_inff()) +template <> +class std::numeric_limits<float> { +public: + [[nodiscard]] static constexpr float infinity() noexcept { + return __builtin_huge_val(); + } +}; + +template <> +class std::numeric_limits<double> { +public: + [[nodiscard]] static constexpr double infinity() noexcept { + return __builtin_huge_val(); + } +}; + template <class _Ty> class numeric_limits { public: @@ -78,6 +102,7 @@ class numeric_limits<float> { return __builtin_huge_val(); } }; + template <> class numeric_limits<double> { public: @@ -86,6 +111,8 @@ class numeric_limits<double> { } }; +double infinity() { return 0; } + int compareit(float a, float b) { volatile int i, j, k, l, m, n, o, p; // no-inf-no-nan-warning@+4 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} @@ -225,11 +252,18 @@ int compareit(float a, float b) { // no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} // no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} - double y = i * numeric_limits<double>::infinity(); + double y = i * std::numeric_limits<double>::infinity(); + + y = i * numeric_limits<double>::infinity(); // expected-no-diagnostics // no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} // no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} - j = numeric_limits<float>::infinity(); + j = std::numeric_limits<float>::infinity(); + + j = numeric_limits<float>::infinity(); // expected-no-diagnostics + + y = infinity(); // expected-no-diagnostics + return 0; } diff --git a/clang/test/Sema/warn-infinity-nan-disabled-win.cpp b/clang/test/Sema/warn-infinity-nan-disabled-win.cpp index ee4eb33a16e449..655024f5909b33 100644 --- a/clang/test/Sema/warn-infinity-nan-disabled-win.cpp +++ b/clang/test/Sema/warn-infinity-nan-disabled-win.cpp @@ -48,24 +48,49 @@ namespace std __attribute__((__visibility__("default"))) { isnan(double __x); bool isnan(long double __x); -bool + bool isfinite(float __x); bool isfinite(double __x); bool isfinte(long double __x); - bool + bool isunordered(float __x, float __y); bool isunordered(double __x, double __y); bool isunordered(long double __x, long double __y); + +template <class _Ty> +class numeric_limits { +public: + [[nodiscard]] static constexpr _Ty infinity() noexcept { + return _Ty(); + } +}; + } // namespace ) } #define INFINITY ((float)(1e+300 * 1e+300)) #define NAN (-(float)(INFINITY * 0.0F)) +template <> +class std::numeric_limits<float> { +public: + [[nodiscard]] static constexpr float infinity() noexcept { + return __builtin_huge_val(); + } +}; + +template <> +class std::numeric_limits<double> { +public: + [[nodiscard]] static constexpr double infinity() noexcept { + return __builtin_huge_val(); + } +}; + template <class _Ty> class numeric_limits { public: @@ -81,6 +106,7 @@ class numeric_limits<float> { return __builtin_huge_val(); } }; + template <> class numeric_limits<double> { public: @@ -89,6 +115,8 @@ class numeric_limits<double> { } }; +double infinity() { return 0; } + int compareit(float a, float b) { volatile int i, j, k, l, m, n, o, p; // no-inf-no-nan-warning@+2 {{use of infinity via a macro is undefined behavior due to the currently enabled floating-point options}} @@ -216,11 +244,18 @@ int compareit(float a, float b) { // no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} // no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} - double y = i * numeric_limits<double>::infinity(); + double y = i * std::numeric_limits<double>::infinity(); + + y = i * numeric_limits<double>::infinity(); // expected-no-diagnostics // no-inf-no-nan-warning@+2 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} // no-inf-warning@+1 {{use of infinity is undefined behavior due to the currently enabled floating-point options}} - j = numeric_limits<float>::infinity(); + j = std::numeric_limits<float>::infinity(); + + j = numeric_limits<float>::infinity(); // expected-no-diagnostics + + y = infinity(); // expected-no-diagnostics + return 0; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits