https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/123417
>From 51dd53feb7a35d4fac648dd165fb5b99f73c6c24 Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Fri, 17 Jan 2025 23:32:48 +0100 Subject: [PATCH 1/3] [Clang] Fix invalid use of infinity warning --- clang/lib/Sema/SemaChecking.cpp | 22 +++++++++- .../Sema/warn-infinity-nan-disabled-lnx.cpp | 42 ++++++++++++++++-- .../Sema/warn-infinity-nan-disabled-win.cpp | 43 +++++++++++++++++-- 3 files changed, 98 insertions(+), 9 deletions(-) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 881907ac311a30..3d2b2e1e96d2dd 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -8454,6 +8454,26 @@ 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) { FPOptions FPO = Call->getFPFeaturesInEffect(getLangOpts()); @@ -8469,7 +8489,7 @@ void Sema::CheckInfNaNFunction(const CallExpr *Call, bool IsInfOrIsFinite = IsStdFunction(FDecl, "isinf") || IsStdFunction(FDecl, "isfinite"); bool IsInfinityOrIsSpecialInf = - HasIdentifier && ((FDecl->getName() == "infinity") || + HasIdentifier && (IsInfinityFunction(FDecl) || IsInfOrNanFunction(FDecl->getName(), MathCheck::Inf)); if ((IsInfOrIsFinite || IsInfinityOrIsSpecialInf) && FPO.getNoHonorInfs()) Diag(Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled) 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; } >From 0023e155b41dad2b6c571162db64c64be9d3596c Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Sat, 18 Jan 2025 18:44:05 +0100 Subject: [PATCH 2/3] Optimize CheckInfNaNFunction function --- clang/lib/Sema/SemaChecking.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 3d2b2e1e96d2dd..d0cdfdad723f3b 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -8476,24 +8476,25 @@ static bool IsInfinityFunction(const FunctionDecl *FDecl) { 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 && (IsInfinityFunction(FDecl) || - 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(); } } >From 0bb6cf1b06d88de0b91ebf394d525497d03fc407 Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Sat, 18 Jan 2025 20:45:55 +0100 Subject: [PATCH 3/3] Add changelog entry --- clang/docs/ReleaseNotes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index aa1c02d04f7caa..2c5cf71bfbe045 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -791,6 +791,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 ---------------------------------- _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits