[clang-tools-extra] [clang-tidy] add modernize-use-std-numbers (PR #66583)

Julian Schmidt via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 4 12:39:05 PST 2023


https://github.com/5chmidti updated https://github.com/llvm/llvm-project/pull/66583

>From 561997a2947354f7112b1dce0b44c8d02bd58da5 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 16 Sep 2023 16:24:13 +0200
Subject: [PATCH 01/44] [clang-tidy] add modernize-use-std-numbers check

This check finds constants and function calls to math functions that can be replaced
with c++20's mathematical constants ('numbers' header) and offers fixit-hints.
Does not match the use of variables or macros with that value and instead, offers a replacement
at the definition of said variables and macros.
---
 .../clang-tidy/modernize/CMakeLists.txt       |   1 +
 .../modernize/ModernizeTidyModule.cpp         |   3 +
 .../modernize/UseStdNumbersCheck.cpp          | 377 ++++++++++++++++++
 .../clang-tidy/modernize/UseStdNumbersCheck.h |  37 ++
 clang-tools-extra/docs/ReleaseNotes.rst       |   6 +
 .../docs/clang-tidy/checks/list.rst           |   1 +
 .../checks/modernize/use-std-numbers.rst      |  25 ++
 .../checkers/modernize/use-std-numbers.cpp    | 205 ++++++++++
 8 files changed, 655 insertions(+)
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
 create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
 create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
 create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp

diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 717c400c47903..d82353d74fbd0 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangTidyModernizeModule
   MakeSharedCheck.cpp
   MakeSmartPtrCheck.cpp
   MakeUniqueCheck.cpp
+  UseStdNumbersCheck.cpp
   ModernizeTidyModule.cpp
   PassByValueCheck.cpp
   RawStringLiteralCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 73751cf270506..73584e20166f6 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -18,6 +18,7 @@
 #include "MacroToEnumCheck.h"
 #include "MakeSharedCheck.h"
 #include "MakeUniqueCheck.h"
+#include "UseStdNumbersCheck.h"
 #include "PassByValueCheck.h"
 #include "RawStringLiteralCheck.h"
 #include "RedundantVoidArgCheck.h"
@@ -65,6 +66,8 @@ class ModernizeModule : public ClangTidyModule {
     CheckFactories.registerCheck<MacroToEnumCheck>("modernize-macro-to-enum");
     CheckFactories.registerCheck<MakeSharedCheck>("modernize-make-shared");
     CheckFactories.registerCheck<MakeUniqueCheck>("modernize-make-unique");
+    CheckFactories.registerCheck<UseStdNumbersCheck>(
+        "modernize-use-std-numbers");
     CheckFactories.registerCheck<PassByValueCheck>("modernize-pass-by-value");
     CheckFactories.registerCheck<UseStdPrintCheck>("modernize-use-std-print");
     CheckFactories.registerCheck<RawStringLiteralCheck>(
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
new file mode 100644
index 0000000000000..c23dc6671013b
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -0,0 +1,377 @@
+//===--- UseStdNumbersCheck.cpp - clang_tidy -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX_License_Identifier: Apache_2.0 WITH LLVM_exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "UseStdNumbersCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersInternal.h"
+#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/TokenKinds.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/Token.h"
+#include "clang/Tooling/Transformer/RewriteRule.h"
+#include "clang/Tooling/Transformer/Stencil.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/MathExtras.h"
+#include <cstdint>
+#include <string>
+
+namespace {
+using namespace clang::ast_matchers;
+using clang::ast_matchers::internal::Matcher;
+using clang::transformer::addInclude;
+using clang::transformer::applyFirst;
+using clang::transformer::ASTEdit;
+using clang::transformer::cat;
+using clang::transformer::changeTo;
+using clang::transformer::edit;
+using clang::transformer::EditGenerator;
+using clang::transformer::flattenVector;
+using clang::transformer::RewriteRuleWith;
+using llvm::StringRef;
+
+constexpr double Pi = 3.141592653589793238462643383279502884197169399;
+constexpr double Euler = 2.718281828459045235360287471352662497757247093;
+constexpr double Phi = 1.618033988749894848204586834365638117720309179;
+constexpr double Egamma = 0.577215664901532860606512090082402431042159335;
+
+constexpr auto DiffThreshold = 0.001;
+
+AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double, Threshold) {
+  return std::abs(Node.getValue().convertToDouble() - Value) < Threshold;
+}
+
+// We don't want to match uses of macros, such as
+//
+// auto PiHalved = MY_PI / 2;
+//
+// because a project might use defines for math constants.
+// Instead, the macro definition is matched and the value is exchanged there.
+// Hinting at replacing macro definitions with language constructs is done in
+// another check.
+AST_MATCHER(clang::Expr, isMathMacro) { return Node.getBeginLoc().isMacroID(); }
+
+AST_MATCHER_P(clang::QualType, hasUnqualifiedDesugaredType,
+              Matcher<clang::QualType>, InnerMatcher) {
+  return InnerMatcher.matches(Node->getCanonicalTypeUnqualified(), Finder,
+                              Builder);
+}
+
+auto matchMathCall(const StringRef FunctionName,
+                   const Matcher<clang::Expr> ArgumentMatcher) {
+  return callExpr(callee(functionDecl(hasName(FunctionName))),
+                  hasArgument(0, ignoringImplicit(ArgumentMatcher)));
+}
+
+auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
+  return matchMathCall("sqrt", ArgumentMatcher);
+}
+
+// 'MatchDeclRefExprOrMacro' is used to differentiate matching expressions where
+// the value of anything used is near 'Val' and matching expressions where we
+// only care about the actual literal.
+// We don't want top-level matches to match a simple DeclRefExpr/macro that was
+// initialized with this value because projects might declare their own
+// constants (e.g. namespaced constants or macros) to be used. We don't want to
+// flag the use of these variables/constants, but modify the definition of the
+// variable or macro.
+//
+// example:
+//   const auto e = 2.71828182; // std::numbers::e
+//                  ^^^^^^^^^^
+//                  match here
+//
+//   auto use = e / 2;
+//              ^
+//   don't match this as a top-level match, this would create noise
+//
+//   auto use2 = log2(e); // std::numbers::log2e
+//               ^^^^^^^
+//               match here, matcher needs to check the initialization
+//               of e to match log2e
+//
+// Therefore, all top-level matcher set MatchDeclRefExprOrMacro to false
+auto matchFloatValueNear(const double Val,
+                         const bool MatchDeclRefExprOrMacro = true) {
+  const auto FloatVal = floatLiteral(near(Val, DiffThreshold));
+  if (!MatchDeclRefExprOrMacro) {
+    return expr(unless(isMathMacro()), ignoringImplicit(FloatVal));
+  }
+
+  const auto Dref = declRefExpr(to(varDecl(
+      anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))),
+      hasInitializer(FloatVal))));
+  return expr(ignoringImplicit(anyOf(FloatVal, Dref)));
+}
+
+auto matchValue(const int64_t ValInt) {
+  const auto Int2 = integerLiteral(equals(ValInt));
+  const auto Float2 = matchFloatValueNear(static_cast<double>(ValInt));
+  const auto Dref = declRefExpr(to(varDecl(
+      anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))),
+      hasInitializer(expr(ignoringImplicit(anyOf(Int2, Float2)))))));
+  return expr(ignoringImplicit(anyOf(Int2, Float2, Dref)));
+}
+
+auto match1Div(const Matcher<clang::Expr> Match) {
+  return binaryOperator(hasOperatorName("/"), hasLHS(matchValue(1)),
+                        hasRHS(ignoringImplicit(Match)));
+}
+
+auto matchEuler() {
+  return expr(
+      anyOf(matchFloatValueNear(Euler), matchMathCall("exp", matchValue(1))));
+}
+auto matchEulerTopLevel() {
+  return expr(anyOf(matchFloatValueNear(Euler, false),
+                    matchMathCall("exp", matchValue(1))));
+}
+
+auto matchLog2Euler() {
+  return expr(anyOf(matchFloatValueNear(llvm::numbers::log2e, false),
+                    matchMathCall("log2", matchEuler())));
+}
+
+auto matchLog10Euler() {
+  return expr(anyOf(matchFloatValueNear(llvm::numbers::log10e, false),
+                    matchMathCall("log10", matchEuler())));
+}
+
+auto matchPi() { return matchFloatValueNear(Pi); }
+auto matchPiTopLevel() { return matchFloatValueNear(Pi, false); }
+
+auto matchEgamma() { return matchFloatValueNear(Egamma, false); }
+
+auto matchInvPi() {
+  return expr(
+      anyOf(matchFloatValueNear(llvm::numbers::inv_pi), match1Div(matchPi())));
+}
+
+auto matchInvSqrtPi() {
+  return expr(anyOf(matchFloatValueNear(llvm::numbers::inv_sqrtpi, false),
+                    match1Div(matchSqrt(matchPi()))));
+}
+
+auto matchLn2() {
+  return expr(anyOf(matchFloatValueNear(llvm::numbers::ln2, false),
+                    matchMathCall("log", ignoringImplicit(matchValue(2)))));
+}
+
+auto machterLn10() {
+  return expr(anyOf(matchFloatValueNear(llvm::numbers::ln10, false),
+                    matchMathCall("log", ignoringImplicit(matchValue(10)))));
+}
+
+auto matchSqrt2() {
+  return expr(anyOf(matchFloatValueNear(llvm::numbers::sqrt2, false),
+                    matchSqrt(matchValue(2))));
+}
+
+auto matchSqrt3() {
+  return expr(anyOf(matchFloatValueNear(llvm::numbers::sqrt3, false),
+                    matchSqrt(matchValue(3))));
+}
+
+auto matchInvSqrt3() {
+  return expr(anyOf(matchFloatValueNear(llvm::numbers::inv_sqrt3, false),
+                    match1Div(matchSqrt(matchValue(3)))));
+}
+
+auto matchPhi() {
+  const auto PhiFormula = binaryOperator(
+      hasOperatorName("/"),
+      hasLHS(parenExpr(has(binaryOperator(
+          hasOperatorName("+"), hasEitherOperand(matchValue(1)),
+          hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
+      hasRHS(matchValue(2)));
+  return expr(anyOf(PhiFormula, matchFloatValueNear(Phi)));
+}
+
+EditGenerator
+chainedIfBound(ASTEdit DefaultEdit,
+               llvm::SmallVector<std::pair<StringRef, ASTEdit>, 2> Edits) {
+  return [Edits = std::move(Edits), DefaultEdit = std::move(DefaultEdit)](
+             const MatchFinder::MatchResult &Result) {
+    auto &Map = Result.Nodes.getMap();
+    for (const auto &[Id, EditOfId] : Edits) {
+      if (Map.find(Id) != Map.end()) {
+        return edit(EditOfId)(Result);
+      }
+    }
+    return edit(DefaultEdit)(Result);
+  };
+}
+
+RewriteRuleWith<std::string> makeRule(const Matcher<clang::Stmt> Matcher,
+                                      const StringRef Constant) {
+  static const auto AddNumbersInclude =
+      addInclude("numbers", clang::transformer::IncludeFormat::Angled);
+
+  const auto DefaultEdit = changeTo(cat("std::numbers::", Constant));
+  const auto FloatEdit = changeTo(cat("std::numbers::", Constant, "_v<float>"));
+  const auto LongDoubleEdit =
+      changeTo(cat("std::numbers::", Constant, "_v<long double>"));
+
+  const auto EditRules = chainedIfBound(
+      DefaultEdit, {{"float", FloatEdit}, {"long double", LongDoubleEdit}});
+
+  return makeRule(
+      expr(Matcher,
+           hasType(qualType(hasCanonicalType(hasUnqualifiedDesugaredType(anyOf(
+               qualType(asString("float")).bind("float"),
+               qualType(asString("double")),
+               qualType(asString("long double")).bind("long double"))))))),
+      flattenVector({edit(AddNumbersInclude), EditRules}),
+      cat("prefer std::numbers math constant"));
+}
+
+/*
+  List of all math constants
+  + e
+  + log2e
+  + log10e
+  + pi
+  + inv_pi
+  + inv_sqrtpi
+  + ln2
+  + ln10
+  + sqrt2
+  + sqrt3
+  + inv_sqrt3
+  + egamma
+  + phi
+*/
+
+RewriteRuleWith<std::string> makeRewriteRule() {
+  return applyFirst({
+      makeRule(matchLog2Euler(), "log2e"),
+      makeRule(matchLog10Euler(), "log10e"),
+      makeRule(matchEulerTopLevel(), "e"),
+      makeRule(matchEgamma(), "egamma"),
+      makeRule(matchInvSqrtPi(), "inv_sqrtpi"),
+      makeRule(matchInvPi(), "inv_pi"),
+      makeRule(matchPiTopLevel(), "pi"),
+      makeRule(matchLn2(), "ln2"),
+      makeRule(machterLn10(), "ln10"),
+      makeRule(matchSqrt2(), "sqrt2"),
+      makeRule(matchInvSqrt3(), "inv_sqrt3"),
+      makeRule(matchSqrt3(), "sqrt3"),
+      makeRule(matchPhi(), "phi"),
+  });
+}
+
+class MathConstantMacroCallback : public clang::PPCallbacks {
+public:
+  explicit MathConstantMacroCallback(
+      clang::tidy::modernize::UseStdNumbersCheck *Check)
+      : Check{Check} {};
+
+  void MacroDefined(const clang::Token & /*MacroNameTok*/,
+                    const clang::MacroDirective *MD) override {
+    for (const auto &Tok : MD->getDefinition().getMacroInfo()->tokens()) {
+      if (!Tok.is(clang::tok::numeric_constant)) {
+        continue;
+      }
+
+      const auto Definition =
+          llvm::StringRef{Tok.getLiteralData(), Tok.getLength()};
+      double Value{};
+      Definition.getAsDouble(Value);
+
+      const auto IsNear = [](const auto Lhs, const auto Rhs) {
+        return std::abs(Lhs - Rhs) < DiffThreshold;
+      };
+
+      if (IsNear(Value, llvm::numbers::log2e)) {
+        reportDiag(Tok, "std::numbers::log2e");
+        return;
+      }
+      if (IsNear(Value, llvm::numbers::log10e)) {
+        reportDiag(Tok, "std::numbers::log10e");
+        return;
+      }
+      if (IsNear(Value, llvm::numbers::e)) {
+        reportDiag(Tok, "std::numbers::e");
+        return;
+      }
+      if (IsNear(Value, llvm::numbers::egamma)) {
+        reportDiag(Tok, "std::numbers::egamma");
+        return;
+      }
+      if (IsNear(Value, llvm::numbers::inv_sqrtpi)) {
+        reportDiag(Tok, "std::numbers::inv_sqrtpi");
+        return;
+      }
+      if (IsNear(Value, llvm::numbers::inv_pi)) {
+        reportDiag(Tok, "std::numbers::inv_pi");
+        return;
+      }
+      if (IsNear(Value, llvm::numbers::pi)) {
+        reportDiag(Tok, "std::numbers::pi");
+        return;
+      }
+      if (IsNear(Value, llvm::numbers::ln2)) {
+        reportDiag(Tok, "std::numbers::ln2");
+        return;
+      }
+      if (IsNear(Value, llvm::numbers::ln10)) {
+        reportDiag(Tok, "std::numbers::ln10");
+        return;
+      }
+      if (IsNear(Value, llvm::numbers::sqrt2)) {
+        reportDiag(Tok, "std::numbers::sqrt2");
+        return;
+      }
+      if (IsNear(Value, llvm::numbers::inv_sqrt3)) {
+        reportDiag(Tok, "std::numbers::inv_sqrt3");
+        return;
+      }
+      if (IsNear(Value, llvm::numbers::sqrt3)) {
+        reportDiag(Tok, "std::numbers::sqrt3");
+        return;
+      }
+      if (IsNear(Value, llvm::numbers::phi)) {
+        reportDiag(Tok, "std::numbers::phi");
+        return;
+      }
+    }
+  }
+
+private:
+  void reportDiag(const clang::Token &Tok, const llvm::StringRef Constant) {
+    Check->diag(Tok.getLocation(), "prefer math constant")
+        << clang::FixItHint::CreateReplacement(
+               clang::SourceRange(Tok.getLocation(), Tok.getLastLoc()),
+               Constant);
+  }
+
+  clang::tidy::modernize::UseStdNumbersCheck *Check{};
+};
+} // namespace
+
+namespace clang::tidy::modernize {
+UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name,
+                                       ClangTidyContext *const Context)
+    : TransformerClangTidyCheck(Name, Context) {
+  setRule(makeRewriteRule());
+}
+
+void UseStdNumbersCheck::registerPPCallbacks(const SourceManager &SM,
+                                             Preprocessor *PP,
+                                             Preprocessor *ModuleExpanderPP) {
+  utils::TransformerClangTidyCheck::registerPPCallbacks(SM, PP,
+                                                        ModuleExpanderPP);
+  PP->addPPCallbacks(std::make_unique<MathConstantMacroCallback>(this));
+}
+} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
new file mode 100644
index 0000000000000..5598d533a3ea7
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
@@ -0,0 +1,37 @@
+//===--- UseStdNumbersCheck.h - clang-tidy ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDNUMBERSCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDNUMBERSCHECK_H
+
+#include "../utils/TransformerClangTidyCheck.h"
+
+namespace clang::tidy::modernize {
+
+/// Finds constants and function calls to math functions that can be replaced
+/// with c++20's mathematical constants ('numbers' header). Does not match the
+/// use of variables or macros with that value and instead offers a replacement
+/// at the definition of said variables and macros.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-numbers.html
+class UseStdNumbersCheck : public utils::TransformerClangTidyCheck {
+public:
+  UseStdNumbersCheck(StringRef Name, ClangTidyContext *Context);
+
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+    return LangOpts.CPlusPlus20;
+  }
+
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
+};
+
+} // namespace clang::tidy::modernize
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDNUMBERSCHECK_H
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 6d5f49dc06254..40f78d06d5af2 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -186,6 +186,12 @@ New checks
 
   Replace ``enable_if`` with C++20 requires clauses.
 
+- New :doc:`modernize-use-std-numbers
+  <clang-tidy/checks/modernize/use-std-numbers>` check.
+
+  Finds constants and function calls to math functions that can be replaced
+  with c++20's mathematical constants ('numbers' header).
+
 - New :doc:`performance-enum-size
   <clang-tidy/checks/performance/enum-size>` check.
 
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 6f987ba1672e3..e753562994f74 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -292,6 +292,7 @@ Clang-Tidy Checks
    :doc:`modernize-use-noexcept <modernize/use-noexcept>`, "Yes"
    :doc:`modernize-use-nullptr <modernize/use-nullptr>`, "Yes"
    :doc:`modernize-use-override <modernize/use-override>`, "Yes"
+   :doc:`modernize-use-std-numbers <modernize/use-std-numbers>`, "Yes"
    :doc:`modernize-use-std-print <modernize/use-std-print>`, "Yes"
    :doc:`modernize-use-trailing-return-type <modernize/use-trailing-return-type>`, "Yes"
    :doc:`modernize-use-transparent-functors <modernize/use-transparent-functors>`, "Yes"
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
new file mode 100644
index 0000000000000..7911f2f7f857b
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -0,0 +1,25 @@
+.. title:: clang-tidy - modernize-use-std-numbers
+
+modernize-use-std-numbers
+=========================
+
+This check finds constants and function calls to math functions that can be replaced
+with c++20's mathematical constants ('numbers' header) and offers fixit-hints.
+Does not match the use of variables or macros with that value and instead, offers a replacement
+at the definition of said variables and macros.
+
+.. code-block:: c++
+    double sqrt(double);
+    double log(double);
+
+    #define MY_PI 3.1415926  // #define MY_PI std::numbers::pi
+
+    void foo() {
+        const double Pi = 3.141592653589;  // const double Pi = std::numbers::pi
+        const auto Use = Pi / 2;           // no match for Pi
+        static constexpr double Euler = 2.7182818; // static constexpr double Euler = std::numbers::e;
+
+        log2(exp(1));     // std::numbers::log2e;
+        log2(Euler);      // std::numbers::log2e;
+        1 / sqrt(MY_PI);  // std::numbers::inv_sqrtpi;
+    }
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
new file mode 100644
index 0000000000000..2ba0525f38306
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -0,0 +1,205 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-std-numbers %t
+
+// CHECK-FIXES: #include <numbers>
+
+namespace bar {
+    double sqrt(double Arg);
+    float sqrt(float Arg);
+    template <typename T>
+    auto sqrt(T val) { return sqrt(static_cast<double>(val)); }
+
+    static constexpr double e = 2.718281828459045235360287471352662497757247093;
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr double e = std::numbers::e;
+}
+
+double exp(double Arg);
+double log(double Arg);
+double log2(double Arg);
+double log10(double Arg);
+
+template<typename T>
+void sink(T&&) { }
+
+#define MY_PI 3.1415926
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer math constant [modernize-use-std-numbers]
+// CHECK-FIXES: #define MY_PI std::numbers::pi
+#define MY_PI2 static_cast<float>(3.1415926)
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers]
+// CHECK-FIXES: #define MY_PI2 static_cast<float>(std::numbers::pi)
+
+#define INV_SQRT3 1 / bar::sqrt(3)
+
+void foo(){
+    static constexpr double Pi = 3.1415926;
+    // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr double Pi = std::numbers::pi;
+
+    static constexpr double Euler = 2.7182818;
+    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr double Euler = std::numbers::e;
+
+    static constexpr double Phi = 1.6180339;
+    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr double Phi = std::numbers::phi;
+
+    static constexpr double PiCopy = Pi;
+    static constexpr double PiDefine = MY_PI;
+
+    // not close enough to match value (DiffThreshold)
+    static constexpr double Pi2 = 3.14;
+    static constexpr double Euler2 = 2.71;
+    static constexpr double Phi2 = 1.61;
+
+    static constexpr double Pi3 = 3.1415926L;
+    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr double Pi3 = std::numbers::pi;
+
+    static constexpr double Euler3 = 2.7182818L;
+    // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr double Euler3 = std::numbers::e;
+
+    static constexpr double Phi3 = 1.6180339L;
+    // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr double Phi3 = std::numbers::phi;
+
+    static constexpr long double Pi4 = 3.1415926L;
+    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr long double Pi4 = std::numbers::pi_v<long double>;
+
+    static constexpr long double Euler4 = 2.7182818L;
+    // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr long double Euler4 = std::numbers::e_v<long double>;
+
+    static constexpr long double Phi4 = 1.6180339L;
+    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
+
+    using my_float = const float;
+    static constexpr my_float Actually2MyFloat = 2;
+    bar::sqrt(Actually2MyFloat);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::sqrt2_v<float>;
+
+    constexpr static auto One = 1;
+    constexpr static auto Two = 2;
+
+    bar::sqrt(2);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::sqrt2;
+
+    bar::sqrt(Two);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::sqrt2;
+
+    bar::sqrt(2.0);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::sqrt2;
+
+    auto Not2 = 2;
+    Not2 = 42;
+    bar::sqrt(Not2);
+
+    const auto Actually2 = 2;
+    bar::sqrt(Actually2);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::sqrt2;
+
+    exp(1);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::e;
+
+    exp(One);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::e;
+
+    exp(1.00000000000001);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::e;
+
+    log2(exp(1));
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::log2e;
+
+    log2(Euler);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::log2e;
+
+    log2(bar::e);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::log2e;
+
+    auto log2e = 1.4426950;
+    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: auto log2e = std::numbers::log2e;
+
+    log10(exp(1));
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::log10e;
+
+    log10(Euler);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::log10e;
+
+    log10(bar::e);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::log10e;
+
+    auto log10e = .434294;
+    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: auto log10e = std::numbers::log10e;
+
+    auto egamma = 0.5772156 * 42;
+    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: auto egamma = std::numbers::egamma * 42;
+
+    sink(1 / Pi);
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: sink(std::numbers::inv_pi);
+
+    sink(1 / bar::sqrt(Pi));
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
+
+    sink(1 / bar::sqrt(MY_PI));
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
+
+
+    log(2);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::ln2;
+
+    log(10);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::ln10;
+
+    bar::sqrt(2);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::sqrt2;
+
+    sink(1 / bar::sqrt(3));
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
+
+    bar::sqrt(3);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::sqrt3;
+
+    auto phi = 1.6180339;
+    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: auto phi = std::numbers::phi;
+
+    sink((42 + bar::sqrt(5)) / 2);
+
+    sink((1 + bar::sqrt(5)) / 2);
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: sink(std::numbers::phi);
+
+    sink((bar::sqrt(5.0F) + 1) / 2);
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: sink(std::numbers::phi_v<float>);
+}

>From 46c5a1e92dc4e7c3f300f88326284abc54f42c80 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 16 Sep 2023 21:19:10 +0200
Subject: [PATCH 02/44] fix lexicographical ordering in some places after
 rename

---
 clang-tools-extra/clang-tidy/modernize/CMakeLists.txt          | 2 +-
 clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index d82353d74fbd0..b254d340c4e85 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -16,7 +16,6 @@ add_clang_library(clangTidyModernizeModule
   MakeSharedCheck.cpp
   MakeSmartPtrCheck.cpp
   MakeUniqueCheck.cpp
-  UseStdNumbersCheck.cpp
   ModernizeTidyModule.cpp
   PassByValueCheck.cpp
   RawStringLiteralCheck.cpp
@@ -39,6 +38,7 @@ add_clang_library(clangTidyModernizeModule
   UseNoexceptCheck.cpp
   UseNullptrCheck.cpp
   UseOverrideCheck.cpp
+  UseStdNumbersCheck.cpp
   UseStdPrintCheck.cpp
   UseTrailingReturnTypeCheck.cpp
   UseTransparentFunctorsCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 73584e20166f6..4f33db5b741a7 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -18,7 +18,6 @@
 #include "MacroToEnumCheck.h"
 #include "MakeSharedCheck.h"
 #include "MakeUniqueCheck.h"
-#include "UseStdNumbersCheck.h"
 #include "PassByValueCheck.h"
 #include "RawStringLiteralCheck.h"
 #include "RedundantVoidArgCheck.h"
@@ -40,6 +39,7 @@
 #include "UseNoexceptCheck.h"
 #include "UseNullptrCheck.h"
 #include "UseOverrideCheck.h"
+#include "UseStdNumbersCheck.h"
 #include "UseStdPrintCheck.h"
 #include "UseTrailingReturnTypeCheck.h"
 #include "UseTransparentFunctorsCheck.h"

>From 4ab522e8e532eb3bc63e0b1726075994c01eab07 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sun, 17 Sep 2023 11:44:58 +0200
Subject: [PATCH 03/44] address comments

- changed ReleaseNotes and first sentence of the check documentation
  by removing parentheses around the numbers header and noted that
  fix-it hints are emitted
---
 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 2 +-
 clang-tools-extra/docs/ReleaseNotes.rst                       | 3 ++-
 .../docs/clang-tidy/checks/modernize/use-std-numbers.rst      | 4 ++--
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index c23dc6671013b..f4bcfb903ad08 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -1,4 +1,4 @@
-//===--- UseStdNumbersCheck.cpp - clang_tidy -------------------------===//
+//===--- UseStdNumbersCheck.cpp - clang_tidy ------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 40f78d06d5af2..6e9a9cb4aacdf 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -190,7 +190,8 @@ New checks
   <clang-tidy/checks/modernize/use-std-numbers>` check.
 
   Finds constants and function calls to math functions that can be replaced
-  with c++20's mathematical constants ('numbers' header).
+  with c++20's mathematical constants from the ``numbers`` header and
+  offers fix-it hints.
 
 - New :doc:`performance-enum-size
   <clang-tidy/checks/performance/enum-size>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
index 7911f2f7f857b..ec443123334f5 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -3,8 +3,8 @@
 modernize-use-std-numbers
 =========================
 
-This check finds constants and function calls to math functions that can be replaced
-with c++20's mathematical constants ('numbers' header) and offers fixit-hints.
+Finds constants and function calls to math functions that can be replaced
+with c++20's mathematical constants from the ``numbers`` header and offers fix-it hints.
 Does not match the use of variables or macros with that value and instead, offers a replacement
 at the definition of said variables and macros.
 

>From 0f63f076a4879e1bccb9a85959dc60d3739a0880 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sun, 17 Sep 2023 18:54:56 +0200
Subject: [PATCH 04/44] update descriptions slightly

- update check description in header to reflect release notes description
- add comma
---
 .../clang-tidy/modernize/UseStdNumbersCheck.h              | 7 ++++---
 .../docs/clang-tidy/checks/modernize/use-std-numbers.rst   | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
index 5598d533a3ea7..9fc98a1892b29 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
@@ -14,9 +14,10 @@
 namespace clang::tidy::modernize {
 
 /// Finds constants and function calls to math functions that can be replaced
-/// with c++20's mathematical constants ('numbers' header). Does not match the
-/// use of variables or macros with that value and instead offers a replacement
-/// at the definition of said variables and macros.
+/// with c++20's mathematical constants from the ``numbers`` header and
+/// offers fix-it hints.
+/// Does not match the use of variables or macros with that value, and instead,
+/// offers a replacement at the definition of said variables and macros.
 ///
 /// For the user-facing documentation see:
 /// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-numbers.html
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
index ec443123334f5..613db21435177 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -5,7 +5,7 @@ modernize-use-std-numbers
 
 Finds constants and function calls to math functions that can be replaced
 with c++20's mathematical constants from the ``numbers`` header and offers fix-it hints.
-Does not match the use of variables or macros with that value and instead, offers a replacement
+Does not match the use of variables or macros with that value, and instead, offers a replacement
 at the definition of said variables and macros.
 
 .. code-block:: c++

>From 5820525955e3fd8c655665e81dacd9738ede30b5 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Mon, 18 Sep 2023 22:15:42 +0200
Subject: [PATCH 05/44] fixup update of warning message

---
 .../modernize/UseStdNumbersCheck.cpp          |  2 +-
 .../checkers/modernize/use-std-numbers.cpp    | 86 +++++++++----------
 2 files changed, 44 insertions(+), 44 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index f4bcfb903ad08..bce0ab2117a48 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -350,7 +350,7 @@ class MathConstantMacroCallback : public clang::PPCallbacks {
 
 private:
   void reportDiag(const clang::Token &Tok, const llvm::StringRef Constant) {
-    Check->diag(Tok.getLocation(), "prefer math constant")
+    Check->diag(Tok.getLocation(), "prefer std::numbers math constant")
         << clang::FixItHint::CreateReplacement(
                clang::SourceRange(Tok.getLocation(), Tok.getLastLoc()),
                Constant);
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 2ba0525f38306..bc9ecdaf8bc92 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -9,7 +9,7 @@ namespace bar {
     auto sqrt(T val) { return sqrt(static_cast<double>(val)); }
 
     static constexpr double e = 2.718281828459045235360287471352662497757247093;
-    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double e = std::numbers::e;
 }
 
@@ -22,25 +22,25 @@ template<typename T>
 void sink(T&&) { }
 
 #define MY_PI 3.1415926
-// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer math constant [modernize-use-std-numbers]
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
 // CHECK-FIXES: #define MY_PI std::numbers::pi
 #define MY_PI2 static_cast<float>(3.1415926)
-// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers]
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
 // CHECK-FIXES: #define MY_PI2 static_cast<float>(std::numbers::pi)
 
 #define INV_SQRT3 1 / bar::sqrt(3)
 
 void foo(){
     static constexpr double Pi = 3.1415926;
-    // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Pi = std::numbers::pi;
 
     static constexpr double Euler = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Euler = std::numbers::e;
 
     static constexpr double Phi = 1.6180339;
-    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Phi = std::numbers::phi;
 
     static constexpr double PiCopy = Pi;
@@ -52,48 +52,48 @@ void foo(){
     static constexpr double Phi2 = 1.61;
 
     static constexpr double Pi3 = 3.1415926L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Pi3 = std::numbers::pi;
 
     static constexpr double Euler3 = 2.7182818L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Euler3 = std::numbers::e;
 
     static constexpr double Phi3 = 1.6180339L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Phi3 = std::numbers::phi;
 
     static constexpr long double Pi4 = 3.1415926L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr long double Pi4 = std::numbers::pi_v<long double>;
 
     static constexpr long double Euler4 = 2.7182818L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr long double Euler4 = std::numbers::e_v<long double>;
 
     static constexpr long double Phi4 = 1.6180339L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
 
     using my_float = const float;
     static constexpr my_float Actually2MyFloat = 2;
     bar::sqrt(Actually2MyFloat);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2_v<float>;
 
     constexpr static auto One = 1;
     constexpr static auto Two = 2;
 
     bar::sqrt(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     bar::sqrt(Two);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     bar::sqrt(2.0);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     auto Not2 = 2;
@@ -102,104 +102,104 @@ void foo(){
 
     const auto Actually2 = 2;
     bar::sqrt(Actually2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     exp(1);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::e;
 
     exp(One);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::e;
 
     exp(1.00000000000001);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::e;
 
     log2(exp(1));
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
     log2(Euler);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
     log2(bar::e);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
     auto log2e = 1.4426950;
-    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: auto log2e = std::numbers::log2e;
 
     log10(exp(1));
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log10e;
 
     log10(Euler);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log10e;
 
     log10(bar::e);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log10e;
 
     auto log10e = .434294;
-    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: auto log10e = std::numbers::log10e;
 
     auto egamma = 0.5772156 * 42;
-    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: auto egamma = std::numbers::egamma * 42;
 
     sink(1 / Pi);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_pi);
 
     sink(1 / bar::sqrt(Pi));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
 
     sink(1 / bar::sqrt(MY_PI));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
 
 
     log(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::ln2;
 
     log(10);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::ln10;
 
     bar::sqrt(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     sink(1 / bar::sqrt(3));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
 
     bar::sqrt(3);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt3;
 
     auto phi = 1.6180339;
-    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: auto phi = std::numbers::phi;
 
     sink((42 + bar::sqrt(5)) / 2);
 
     sink((1 + bar::sqrt(5)) / 2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::phi);
 
     sink((bar::sqrt(5.0F) + 1) / 2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::phi_v<float>);
 }

>From 6a75cbe8cfcb916f50cd6edc7f52f533716b9e8b Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Mon, 25 Sep 2023 12:42:21 +0200
Subject: [PATCH 06/44] rename isMathMacro to isMacro

---
 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index bce0ab2117a48..7fa4d00d45520 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -60,7 +60,7 @@ AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double, Threshold) {
 // Instead, the macro definition is matched and the value is exchanged there.
 // Hinting at replacing macro definitions with language constructs is done in
 // another check.
-AST_MATCHER(clang::Expr, isMathMacro) { return Node.getBeginLoc().isMacroID(); }
+AST_MATCHER(clang::Expr, isMacro) { return Node.getBeginLoc().isMacroID(); }
 
 AST_MATCHER_P(clang::QualType, hasUnqualifiedDesugaredType,
               Matcher<clang::QualType>, InnerMatcher) {
@@ -106,7 +106,7 @@ auto matchFloatValueNear(const double Val,
                          const bool MatchDeclRefExprOrMacro = true) {
   const auto FloatVal = floatLiteral(near(Val, DiffThreshold));
   if (!MatchDeclRefExprOrMacro) {
-    return expr(unless(isMathMacro()), ignoringImplicit(FloatVal));
+    return expr(unless(isMacro()), ignoringImplicit(FloatVal));
   }
 
   const auto Dref = declRefExpr(to(varDecl(

>From 670c9e0e5a0a925d28ae5027d3e8c4b61eacf4af Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Mon, 25 Sep 2023 13:14:53 +0200
Subject: [PATCH 07/44] add tests for uses in templates

- dont match in template instantiations
---
 .../modernize/UseStdNumbersCheck.cpp          |   2 +-
 .../checkers/modernize/use-std-numbers.cpp    | 160 ++++++++++++++++++
 2 files changed, 161 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 7fa4d00d45520..db92a1f50b7bc 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -227,7 +227,7 @@ RewriteRuleWith<std::string> makeRule(const Matcher<clang::Stmt> Matcher,
       DefaultEdit, {{"float", FloatEdit}, {"long double", LongDoubleEdit}});
 
   return makeRule(
-      expr(Matcher,
+      expr(Matcher, unless(isInTemplateInstantiation()),
            hasType(qualType(hasCanonicalType(hasUnqualifiedDesugaredType(anyOf(
                qualType(asString("float")).bind("float"),
                qualType(asString("double")),
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index bc9ecdaf8bc92..8914ffc1e05f4 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -203,3 +203,163 @@ void foo(){
     // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::phi_v<float>);
 }
+
+
+
+template <typename T>
+void baz(){
+    static constexpr T Pi = 3.1415926;
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr T Pi = std::numbers::pi;
+
+    static constexpr T Euler = 2.7182818;
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr T Euler = std::numbers::e;
+
+    static constexpr T Phi = 1.6180339;
+    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr T Phi = std::numbers::phi;
+
+    static constexpr T PiCopy = Pi;
+    static constexpr T PiDefine = MY_PI;
+
+    // not close enough to match value (DiffThreshold)
+    static constexpr T Pi2 = 3.14;
+    static constexpr T Euler2 = 2.71;
+    static constexpr T Phi2 = 1.61;
+
+    static constexpr T Pi3 = 3.1415926L;
+    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr T Pi3 = std::numbers::pi_v<long double>;
+
+    static constexpr T Euler3 = 2.7182818L;
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr T Euler3 = std::numbers::e_v<long double>;
+
+    static constexpr T Phi3 = 1.6180339L;
+    // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr T Phi3 = std::numbers::phi_v<long double>;
+
+    using my_float = const float;
+    static constexpr my_float Actually2MyFloat = 2;
+    bar::sqrt(Actually2MyFloat);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::sqrt2_v<float>;
+
+    constexpr static T One = 1;
+    constexpr static T Two = 2;
+
+    bar::sqrt(2);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::sqrt2;
+
+    bar::sqrt(Two);
+
+    bar::sqrt(2.0);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::sqrt2;
+
+    T Not2 = 2;
+    Not2 = 42;
+    bar::sqrt(Not2);
+
+    const T Actually2 = 2;
+    bar::sqrt(Actually2);
+
+    exp(1);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::e;
+
+    exp(One);
+
+    exp(1.00000000000001);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::e;
+
+    log2(exp(1));
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::log2e;
+
+    log2(Euler);
+
+    log2(bar::e);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::log2e;
+
+    T log2e = 1.4426950;
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: T log2e = std::numbers::log2e;
+
+    log10(exp(1));
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::log10e;
+
+    log10(Euler);
+
+    log10(bar::e);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::log10e;
+
+    T log10e = .434294;
+    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: T log10e = std::numbers::log10e;
+
+    T egamma = 0.5772156 * 42;
+    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: T egamma = std::numbers::egamma * 42;
+
+    sink(1 / Pi);
+
+    sink(1 / bar::sqrt(Pi));
+
+    sink(1 / bar::sqrt(MY_PI));
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
+
+
+    log(2);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::ln2;
+
+    log(10);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::ln10;
+
+    bar::sqrt(2);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::sqrt2;
+
+    sink(1 / bar::sqrt(3));
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
+
+    bar::sqrt(3);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::sqrt3;
+
+    T phi = 1.6180339;
+    // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: T phi = std::numbers::phi;
+
+    sink((42 + bar::sqrt(5)) / 2);
+
+    sink((1 + bar::sqrt(5)) / 2);
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: sink(std::numbers::phi);
+
+    sink((bar::sqrt(5.0F) + 1) / 2);
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: sink(std::numbers::phi_v<float>);
+}
+
+template <typename T>
+void foobar(){
+    const T Two = 2;
+    bar::sqrt(Two);
+}
+void use_foobar() {
+    foobar<float>();
+}

>From 2c90f626a6426b1eafa65d5f942d40f6a11ed5a5 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Mon, 25 Sep 2023 13:15:04 +0200
Subject: [PATCH 08/44] fix matcher names

---
 .../clang-tidy/modernize/UseStdNumbersCheck.cpp  | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index db92a1f50b7bc..8b3fa976b74d4 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -104,24 +104,24 @@ auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
 // Therefore, all top-level matcher set MatchDeclRefExprOrMacro to false
 auto matchFloatValueNear(const double Val,
                          const bool MatchDeclRefExprOrMacro = true) {
-  const auto FloatVal = floatLiteral(near(Val, DiffThreshold));
+  const auto Float = floatLiteral(near(Val, DiffThreshold));
   if (!MatchDeclRefExprOrMacro) {
-    return expr(unless(isMacro()), ignoringImplicit(FloatVal));
+    return expr(unless(isMacro()), ignoringImplicit(Float));
   }
 
   const auto Dref = declRefExpr(to(varDecl(
       anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))),
-      hasInitializer(FloatVal))));
-  return expr(ignoringImplicit(anyOf(FloatVal, Dref)));
+      hasInitializer(Float))));
+  return expr(ignoringImplicit(anyOf(Float, Dref)));
 }
 
 auto matchValue(const int64_t ValInt) {
-  const auto Int2 = integerLiteral(equals(ValInt));
-  const auto Float2 = matchFloatValueNear(static_cast<double>(ValInt));
+  const auto Int = integerLiteral(equals(ValInt));
+  const auto Float = matchFloatValueNear(static_cast<double>(ValInt));
   const auto Dref = declRefExpr(to(varDecl(
       anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))),
-      hasInitializer(expr(ignoringImplicit(anyOf(Int2, Float2)))))));
-  return expr(ignoringImplicit(anyOf(Int2, Float2, Dref)));
+      hasInitializer(expr(ignoringImplicit(anyOf(Int, Float)))))));
+  return expr(ignoringImplicit(anyOf(Int, Float, Dref)));
 }
 
 auto match1Div(const Matcher<clang::Expr> Match) {

>From 8acc5e86e08012ca74cc9e0f43407b52844467a8 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 7 Oct 2023 17:58:15 +0200
Subject: [PATCH 09/44] fix name of custom matcher hasCanonicalTypeUnqualified

---
 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 8b3fa976b74d4..6fe31c43115ab 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -62,7 +62,7 @@ AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double, Threshold) {
 // another check.
 AST_MATCHER(clang::Expr, isMacro) { return Node.getBeginLoc().isMacroID(); }
 
-AST_MATCHER_P(clang::QualType, hasUnqualifiedDesugaredType,
+AST_MATCHER_P(clang::QualType, hasCanonicalTypeUnqualified,
               Matcher<clang::QualType>, InnerMatcher) {
   return InnerMatcher.matches(Node->getCanonicalTypeUnqualified(), Finder,
                               Builder);
@@ -228,7 +228,7 @@ RewriteRuleWith<std::string> makeRule(const Matcher<clang::Stmt> Matcher,
 
   return makeRule(
       expr(Matcher, unless(isInTemplateInstantiation()),
-           hasType(qualType(hasCanonicalType(hasUnqualifiedDesugaredType(anyOf(
+           hasType(qualType(hasCanonicalType(hasCanonicalTypeUnqualified(anyOf(
                qualType(asString("float")).bind("float"),
                qualType(asString("double")),
                qualType(asString("long double")).bind("long double"))))))),

>From 5e7e11f5dc0badcbd7fca8ff4fbea9a3e62c543b Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 7 Oct 2023 18:01:50 +0200
Subject: [PATCH 10/44] remove custom constants in favor of using llvm::numbers
 for all

---
 .../modernize/UseStdNumbersCheck.cpp          | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 6fe31c43115ab..799b5cc2aaa81 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -41,11 +41,6 @@ using clang::transformer::flattenVector;
 using clang::transformer::RewriteRuleWith;
 using llvm::StringRef;
 
-constexpr double Pi = 3.141592653589793238462643383279502884197169399;
-constexpr double Euler = 2.718281828459045235360287471352662497757247093;
-constexpr double Phi = 1.618033988749894848204586834365638117720309179;
-constexpr double Egamma = 0.577215664901532860606512090082402431042159335;
-
 constexpr auto DiffThreshold = 0.001;
 
 AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double, Threshold) {
@@ -130,11 +125,11 @@ auto match1Div(const Matcher<clang::Expr> Match) {
 }
 
 auto matchEuler() {
-  return expr(
-      anyOf(matchFloatValueNear(Euler), matchMathCall("exp", matchValue(1))));
+  return expr(anyOf(matchFloatValueNear(llvm::numbers::e),
+                    matchMathCall("exp", matchValue(1))));
 }
 auto matchEulerTopLevel() {
-  return expr(anyOf(matchFloatValueNear(Euler, false),
+  return expr(anyOf(matchFloatValueNear(llvm::numbers::e, false),
                     matchMathCall("exp", matchValue(1))));
 }
 
@@ -148,10 +143,10 @@ auto matchLog10Euler() {
                     matchMathCall("log10", matchEuler())));
 }
 
-auto matchPi() { return matchFloatValueNear(Pi); }
-auto matchPiTopLevel() { return matchFloatValueNear(Pi, false); }
+auto matchPi() { return matchFloatValueNear(llvm::numbers::pi); }
+auto matchPiTopLevel() { return matchFloatValueNear(llvm::numbers::pi, false); }
 
-auto matchEgamma() { return matchFloatValueNear(Egamma, false); }
+auto matchEgamma() { return matchFloatValueNear(llvm::numbers::egamma, false); }
 
 auto matchInvPi() {
   return expr(
@@ -195,7 +190,7 @@ auto matchPhi() {
           hasOperatorName("+"), hasEitherOperand(matchValue(1)),
           hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
       hasRHS(matchValue(2)));
-  return expr(anyOf(PhiFormula, matchFloatValueNear(Phi)));
+  return expr(anyOf(PhiFormula, matchFloatValueNear(llvm::numbers::phi)));
 }
 
 EditGenerator

>From 44330fc5dd5eae24f42f7e07d8d3acccdc9252aa Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 7 Oct 2023 18:03:19 +0200
Subject: [PATCH 11/44] remove not needed argument for using a compile-time
 constant

---
 .../clang-tidy/modernize/UseStdNumbersCheck.cpp             | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 799b5cc2aaa81..9e8863c91d0ff 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -43,8 +43,8 @@ using llvm::StringRef;
 
 constexpr auto DiffThreshold = 0.001;
 
-AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double, Threshold) {
-  return std::abs(Node.getValue().convertToDouble() - Value) < Threshold;
+AST_MATCHER_P(clang::FloatingLiteral, near, double, Value) {
+  return std::abs(Node.getValue().convertToDouble() - Value) < DiffThreshold;
 }
 
 // We don't want to match uses of macros, such as
@@ -99,7 +99,7 @@ auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
 // Therefore, all top-level matcher set MatchDeclRefExprOrMacro to false
 auto matchFloatValueNear(const double Val,
                          const bool MatchDeclRefExprOrMacro = true) {
-  const auto Float = floatLiteral(near(Val, DiffThreshold));
+  const auto Float = floatLiteral(near(Val));
   if (!MatchDeclRefExprOrMacro) {
     return expr(unless(isMacro()), ignoringImplicit(Float));
   }

>From 67c1d05538b846710ba04d4f973344b1755b51cd Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 7 Oct 2023 18:14:24 +0200
Subject: [PATCH 12/44] fix inv_pi and phi matchers matching uses of named
 constants

---
 .../clang-tidy/modernize/UseStdNumbersCheck.cpp           | 7 ++++---
 .../clang-tidy/checkers/modernize/use-std-numbers.cpp     | 8 ++++++++
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 9e8863c91d0ff..2939a0f1d9ca7 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -149,8 +149,8 @@ auto matchPiTopLevel() { return matchFloatValueNear(llvm::numbers::pi, false); }
 auto matchEgamma() { return matchFloatValueNear(llvm::numbers::egamma, false); }
 
 auto matchInvPi() {
-  return expr(
-      anyOf(matchFloatValueNear(llvm::numbers::inv_pi), match1Div(matchPi())));
+  return expr(anyOf(matchFloatValueNear(llvm::numbers::inv_pi, false),
+                    match1Div(matchPi())));
 }
 
 auto matchInvSqrtPi() {
@@ -190,7 +190,8 @@ auto matchPhi() {
           hasOperatorName("+"), hasEitherOperand(matchValue(1)),
           hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
       hasRHS(matchValue(2)));
-  return expr(anyOf(PhiFormula, matchFloatValueNear(llvm::numbers::phi)));
+  return expr(
+      anyOf(PhiFormula, matchFloatValueNear(llvm::numbers::phi, false)));
 }
 
 EditGenerator
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 8914ffc1e05f4..19efa3291ea36 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -75,6 +75,10 @@ void foo(){
     // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
 
+    static constexpr double InvPi = 1.0 / Pi;
+    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr double InvPi = std::numbers::inv_pi;
+
     using my_float = const float;
     static constexpr my_float Actually2MyFloat = 2;
     bar::sqrt(Actually2MyFloat);
@@ -155,6 +159,8 @@ void foo(){
     // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: auto egamma = std::numbers::egamma * 42;
 
+    sink(InvPi);
+
     sink(1 / Pi);
     // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_pi);
@@ -193,6 +199,8 @@ void foo(){
     // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: auto phi = std::numbers::phi;
 
+    sink(Phi);
+
     sink((42 + bar::sqrt(5)) / 2);
 
     sink((1 + bar::sqrt(5)) / 2);

>From 2d01edc97131f66bdbe8fd45be3d85c7b8aaacb7 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 27 Oct 2023 23:00:58 +0200
Subject: [PATCH 13/44] change matches of macro defs to macro uses

- modernizes the usage of macros to the std::numbers constants
- removes PPCallback that failed CI
- change comments and docs
---
 .../modernize/UseStdNumbersCheck.cpp          | 112 ------------------
 .../clang-tidy/modernize/UseStdNumbersCheck.h |   7 +-
 .../checks/modernize/use-std-numbers.rst      |   8 +-
 .../checkers/modernize/use-std-numbers.cpp    |  20 ++--
 4 files changed, 19 insertions(+), 128 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 2939a0f1d9ca7..acbdcde06b329 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -14,12 +14,6 @@
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/ASTMatchers/ASTMatchersInternal.h"
 #include "clang/ASTMatchers/ASTMatchersMacros.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/TokenKinds.h"
-#include "clang/Lex/PPCallbacks.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/Token.h"
 #include "clang/Tooling/Transformer/RewriteRule.h"
 #include "clang/Tooling/Transformer/Stencil.h"
 #include "llvm/ADT/StringRef.h"
@@ -47,16 +41,6 @@ AST_MATCHER_P(clang::FloatingLiteral, near, double, Value) {
   return std::abs(Node.getValue().convertToDouble() - Value) < DiffThreshold;
 }
 
-// We don't want to match uses of macros, such as
-//
-// auto PiHalved = MY_PI / 2;
-//
-// because a project might use defines for math constants.
-// Instead, the macro definition is matched and the value is exchanged there.
-// Hinting at replacing macro definitions with language constructs is done in
-// another check.
-AST_MATCHER(clang::Expr, isMacro) { return Node.getBeginLoc().isMacroID(); }
-
 AST_MATCHER_P(clang::QualType, hasCanonicalTypeUnqualified,
               Matcher<clang::QualType>, InnerMatcher) {
   return InnerMatcher.matches(Node->getCanonicalTypeUnqualified(), Finder,
@@ -266,94 +250,6 @@ RewriteRuleWith<std::string> makeRewriteRule() {
       makeRule(matchPhi(), "phi"),
   });
 }
-
-class MathConstantMacroCallback : public clang::PPCallbacks {
-public:
-  explicit MathConstantMacroCallback(
-      clang::tidy::modernize::UseStdNumbersCheck *Check)
-      : Check{Check} {};
-
-  void MacroDefined(const clang::Token & /*MacroNameTok*/,
-                    const clang::MacroDirective *MD) override {
-    for (const auto &Tok : MD->getDefinition().getMacroInfo()->tokens()) {
-      if (!Tok.is(clang::tok::numeric_constant)) {
-        continue;
-      }
-
-      const auto Definition =
-          llvm::StringRef{Tok.getLiteralData(), Tok.getLength()};
-      double Value{};
-      Definition.getAsDouble(Value);
-
-      const auto IsNear = [](const auto Lhs, const auto Rhs) {
-        return std::abs(Lhs - Rhs) < DiffThreshold;
-      };
-
-      if (IsNear(Value, llvm::numbers::log2e)) {
-        reportDiag(Tok, "std::numbers::log2e");
-        return;
-      }
-      if (IsNear(Value, llvm::numbers::log10e)) {
-        reportDiag(Tok, "std::numbers::log10e");
-        return;
-      }
-      if (IsNear(Value, llvm::numbers::e)) {
-        reportDiag(Tok, "std::numbers::e");
-        return;
-      }
-      if (IsNear(Value, llvm::numbers::egamma)) {
-        reportDiag(Tok, "std::numbers::egamma");
-        return;
-      }
-      if (IsNear(Value, llvm::numbers::inv_sqrtpi)) {
-        reportDiag(Tok, "std::numbers::inv_sqrtpi");
-        return;
-      }
-      if (IsNear(Value, llvm::numbers::inv_pi)) {
-        reportDiag(Tok, "std::numbers::inv_pi");
-        return;
-      }
-      if (IsNear(Value, llvm::numbers::pi)) {
-        reportDiag(Tok, "std::numbers::pi");
-        return;
-      }
-      if (IsNear(Value, llvm::numbers::ln2)) {
-        reportDiag(Tok, "std::numbers::ln2");
-        return;
-      }
-      if (IsNear(Value, llvm::numbers::ln10)) {
-        reportDiag(Tok, "std::numbers::ln10");
-        return;
-      }
-      if (IsNear(Value, llvm::numbers::sqrt2)) {
-        reportDiag(Tok, "std::numbers::sqrt2");
-        return;
-      }
-      if (IsNear(Value, llvm::numbers::inv_sqrt3)) {
-        reportDiag(Tok, "std::numbers::inv_sqrt3");
-        return;
-      }
-      if (IsNear(Value, llvm::numbers::sqrt3)) {
-        reportDiag(Tok, "std::numbers::sqrt3");
-        return;
-      }
-      if (IsNear(Value, llvm::numbers::phi)) {
-        reportDiag(Tok, "std::numbers::phi");
-        return;
-      }
-    }
-  }
-
-private:
-  void reportDiag(const clang::Token &Tok, const llvm::StringRef Constant) {
-    Check->diag(Tok.getLocation(), "prefer std::numbers math constant")
-        << clang::FixItHint::CreateReplacement(
-               clang::SourceRange(Tok.getLocation(), Tok.getLastLoc()),
-               Constant);
-  }
-
-  clang::tidy::modernize::UseStdNumbersCheck *Check{};
-};
 } // namespace
 
 namespace clang::tidy::modernize {
@@ -362,12 +258,4 @@ UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name,
     : TransformerClangTidyCheck(Name, Context) {
   setRule(makeRewriteRule());
 }
-
-void UseStdNumbersCheck::registerPPCallbacks(const SourceManager &SM,
-                                             Preprocessor *PP,
-                                             Preprocessor *ModuleExpanderPP) {
-  utils::TransformerClangTidyCheck::registerPPCallbacks(SM, PP,
-                                                        ModuleExpanderPP);
-  PP->addPPCallbacks(std::make_unique<MathConstantMacroCallback>(this));
-}
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
index 9fc98a1892b29..3cf2d9244cc81 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
@@ -16,8 +16,8 @@ namespace clang::tidy::modernize {
 /// Finds constants and function calls to math functions that can be replaced
 /// with c++20's mathematical constants from the ``numbers`` header and
 /// offers fix-it hints.
-/// Does not match the use of variables or macros with that value, and instead,
-/// offers a replacement at the definition of said variables and macros.
+/// Does not match the use of variables with that value, and instead,
+/// offers a replacement at the definition of those variables.
 ///
 /// For the user-facing documentation see:
 /// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-numbers.html
@@ -28,9 +28,6 @@ class UseStdNumbersCheck : public utils::TransformerClangTidyCheck {
   bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
     return LangOpts.CPlusPlus20;
   }
-
-  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
-                           Preprocessor *ModuleExpanderPP) override;
 };
 
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
index 613db21435177..5da01bd34eaf6 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -5,14 +5,15 @@ modernize-use-std-numbers
 
 Finds constants and function calls to math functions that can be replaced
 with c++20's mathematical constants from the ``numbers`` header and offers fix-it hints.
-Does not match the use of variables or macros with that value, and instead, offers a replacement
-at the definition of said variables and macros.
+Does not match the use of variables with that value, and instead,
+offers a replacement at the definition of those variables.
 
 .. code-block:: c++
     double sqrt(double);
     double log(double);
+    void sink(auto&&) {}
 
-    #define MY_PI 3.1415926  // #define MY_PI std::numbers::pi
+    #define MY_PI 3.1415926
 
     void foo() {
         const double Pi = 3.141592653589;  // const double Pi = std::numbers::pi
@@ -22,4 +23,5 @@ at the definition of said variables and macros.
         log2(exp(1));     // std::numbers::log2e;
         log2(Euler);      // std::numbers::log2e;
         1 / sqrt(MY_PI);  // std::numbers::inv_sqrtpi;
+        sink(MY_PI);      // sink(std::numbers::pi);
     }
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 19efa3291ea36..8fce42b901b1a 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -22,11 +22,6 @@ template<typename T>
 void sink(T&&) { }
 
 #define MY_PI 3.1415926
-// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-// CHECK-FIXES: #define MY_PI std::numbers::pi
-#define MY_PI2 static_cast<float>(3.1415926)
-// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-// CHECK-FIXES: #define MY_PI2 static_cast<float>(std::numbers::pi)
 
 #define INV_SQRT3 1 / bar::sqrt(3)
 
@@ -44,7 +39,9 @@ void foo(){
     // CHECK-FIXES: static constexpr double Phi = std::numbers::phi;
 
     static constexpr double PiCopy = Pi;
-    static constexpr double PiDefine = MY_PI;
+    static constexpr double PiDefineFromMacro = MY_PI;
+    // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr double PiDefineFromMacro = std::numbers::pi;
 
     // not close enough to match value (DiffThreshold)
     static constexpr double Pi2 = 3.14;
@@ -171,9 +168,9 @@ void foo(){
 
     sink(1 / bar::sqrt(MY_PI));
     // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
 
-
     log(2);
     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::ln2;
@@ -191,6 +188,10 @@ void foo(){
     // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
 
+    sink(INV_SQRT3);
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
+
     bar::sqrt(3);
     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt3;
@@ -229,7 +230,9 @@ void baz(){
     // CHECK-FIXES: static constexpr T Phi = std::numbers::phi;
 
     static constexpr T PiCopy = Pi;
-    static constexpr T PiDefine = MY_PI;
+    static constexpr T PiDefineFromMacro = MY_PI;
+    // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr T PiDefineFromMacro = std::numbers::pi;
 
     // not close enough to match value (DiffThreshold)
     static constexpr T Pi2 = 3.14;
@@ -324,6 +327,7 @@ void baz(){
 
     sink(1 / bar::sqrt(MY_PI));
     // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
 
 

>From 040d67d3243186e05dc1b9589ceda993167101d2 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 27 Oct 2023 23:03:23 +0200
Subject: [PATCH 14/44] split matcher for float values

- removes the optional bool flag
- improves readability for matchers
- split the comment
---
 .../modernize/UseStdNumbersCheck.cpp          | 72 +++++++++----------
 1 file changed, 33 insertions(+), 39 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index acbdcde06b329..98beab00a0181 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -8,6 +8,7 @@
 
 #include "UseStdNumbersCheck.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/Type.h"
@@ -57,36 +58,30 @@ auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
   return matchMathCall("sqrt", ArgumentMatcher);
 }
 
-// 'MatchDeclRefExprOrMacro' is used to differentiate matching expressions where
-// the value of anything used is near 'Val' and matching expressions where we
-// only care about the actual literal.
-// We don't want top-level matches to match a simple DeclRefExpr/macro that was
-// initialized with this value because projects might declare their own
-// constants (e.g. namespaced constants or macros) to be used. We don't want to
-// flag the use of these variables/constants, but modify the definition of the
-// variable or macro.
+// Used for top-level matchers (i.e. the match that replaces Val with its
+// constant).
 //
-// example:
-//   const auto e = 2.71828182; // std::numbers::e
-//                  ^^^^^^^^^^
-//                  match here
+// E.g. The matcher of `std::numbers::pi` uses this matcher to look to
+// floatLiterals that have the value of pi.
 //
-//   auto use = e / 2;
-//              ^
-//   don't match this as a top-level match, this would create noise
+// We only care about the literal if the match is for a top-level match
+auto matchFloatLiteralNear(const double Val) {
+  return expr(ignoringImplicit(floatLiteral(near(Val))));
+}
+
+// Used for non-top-level matchers (i.e. matchers that are used as inner
+// matchers for top-level matchers).
 //
-//   auto use2 = log2(e); // std::numbers::log2e
-//               ^^^^^^^
-//               match here, matcher needs to check the initialization
-//               of e to match log2e
+// E.g.: The matcher of `std::numbers::log2e` uses this matcher to check if `e`
+// of `log2(e)` is declared constant and initialized with the value for eulers
+// number.
 //
-// Therefore, all top-level matcher set MatchDeclRefExprOrMacro to false
-auto matchFloatValueNear(const double Val,
-                         const bool MatchDeclRefExprOrMacro = true) {
+// Here, we do care about literals and about DeclRefExprs to variable
+// declarations that are constant and initialized with `Val`. This allows
+// top-level matchers to see through declared constants for their inner matches
+// like the `std::numbers::log2e` matcher.
+auto matchFloatValueNear(const double Val) {
   const auto Float = floatLiteral(near(Val));
-  if (!MatchDeclRefExprOrMacro) {
-    return expr(unless(isMacro()), ignoringImplicit(Float));
-  }
 
   const auto Dref = declRefExpr(to(varDecl(
       anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))),
@@ -113,57 +108,57 @@ auto matchEuler() {
                     matchMathCall("exp", matchValue(1))));
 }
 auto matchEulerTopLevel() {
-  return expr(anyOf(matchFloatValueNear(llvm::numbers::e, false),
+  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::e),
                     matchMathCall("exp", matchValue(1))));
 }
 
 auto matchLog2Euler() {
-  return expr(anyOf(matchFloatValueNear(llvm::numbers::log2e, false),
+  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::log2e),
                     matchMathCall("log2", matchEuler())));
 }
 
 auto matchLog10Euler() {
-  return expr(anyOf(matchFloatValueNear(llvm::numbers::log10e, false),
+  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::log10e),
                     matchMathCall("log10", matchEuler())));
 }
 
 auto matchPi() { return matchFloatValueNear(llvm::numbers::pi); }
-auto matchPiTopLevel() { return matchFloatValueNear(llvm::numbers::pi, false); }
+auto matchPiTopLevel() { return matchFloatLiteralNear(llvm::numbers::pi); }
 
-auto matchEgamma() { return matchFloatValueNear(llvm::numbers::egamma, false); }
+auto matchEgamma() { return matchFloatLiteralNear(llvm::numbers::egamma); }
 
 auto matchInvPi() {
-  return expr(anyOf(matchFloatValueNear(llvm::numbers::inv_pi, false),
+  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::inv_pi),
                     match1Div(matchPi())));
 }
 
 auto matchInvSqrtPi() {
-  return expr(anyOf(matchFloatValueNear(llvm::numbers::inv_sqrtpi, false),
+  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::inv_sqrtpi),
                     match1Div(matchSqrt(matchPi()))));
 }
 
 auto matchLn2() {
-  return expr(anyOf(matchFloatValueNear(llvm::numbers::ln2, false),
+  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::ln2),
                     matchMathCall("log", ignoringImplicit(matchValue(2)))));
 }
 
 auto machterLn10() {
-  return expr(anyOf(matchFloatValueNear(llvm::numbers::ln10, false),
+  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::ln10),
                     matchMathCall("log", ignoringImplicit(matchValue(10)))));
 }
 
 auto matchSqrt2() {
-  return expr(anyOf(matchFloatValueNear(llvm::numbers::sqrt2, false),
+  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::sqrt2),
                     matchSqrt(matchValue(2))));
 }
 
 auto matchSqrt3() {
-  return expr(anyOf(matchFloatValueNear(llvm::numbers::sqrt3, false),
+  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::sqrt3),
                     matchSqrt(matchValue(3))));
 }
 
 auto matchInvSqrt3() {
-  return expr(anyOf(matchFloatValueNear(llvm::numbers::inv_sqrt3, false),
+  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::inv_sqrt3),
                     match1Div(matchSqrt(matchValue(3)))));
 }
 
@@ -174,8 +169,7 @@ auto matchPhi() {
           hasOperatorName("+"), hasEitherOperand(matchValue(1)),
           hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
       hasRHS(matchValue(2)));
-  return expr(
-      anyOf(PhiFormula, matchFloatValueNear(llvm::numbers::phi, false)));
+  return expr(anyOf(PhiFormula, matchFloatLiteralNear(llvm::numbers::phi)));
 }
 
 EditGenerator

>From e26977801b541e0379f109c112a9451672e79f28 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 27 Oct 2023 23:09:01 +0200
Subject: [PATCH 15/44] add test of using math marco on its own

---
 .../test/clang-tidy/checkers/modernize/use-std-numbers.cpp    | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 8fce42b901b1a..2ceec289ce7c1 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -82,6 +82,10 @@ void foo(){
     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2_v<float>;
 
+    sink(MY_PI);
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: sink(std::numbers::pi);
+
     constexpr static auto One = 1;
     constexpr static auto Two = 2;
 

>From b6e3497c3170f36daca89f8ca554149d938f4bbe Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 27 Oct 2023 23:28:30 +0200
Subject: [PATCH 16/44] add newline after code-block directive to maybe fix
 docs ci

---
 .../docs/clang-tidy/checks/modernize/use-std-numbers.rst         | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
index 5da01bd34eaf6..8cd3149879282 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -9,6 +9,7 @@ Does not match the use of variables with that value, and instead,
 offers a replacement at the definition of those variables.
 
 .. code-block:: c++
+
     double sqrt(double);
     double log(double);
     void sink(auto&&) {}

>From 53eb3c7a4409d228fb2cace6a8cb7039706fdb61 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 28 Oct 2023 01:45:11 +0200
Subject: [PATCH 17/44] fix APFloat issue

---
 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 98beab00a0181..257ede0897d71 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -39,7 +39,7 @@ using llvm::StringRef;
 constexpr auto DiffThreshold = 0.001;
 
 AST_MATCHER_P(clang::FloatingLiteral, near, double, Value) {
-  return std::abs(Node.getValue().convertToDouble() - Value) < DiffThreshold;
+  return std::abs(Node.getValueAsApproximateDouble() - Value) < DiffThreshold;
 }
 
 AST_MATCHER_P(clang::QualType, hasCanonicalTypeUnqualified,

>From dc26f3e59294e3f331231a3d281b5f0ce64370de Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 28 Oct 2023 01:45:19 +0200
Subject: [PATCH 18/44] run clang-include-cleaner

---
 .../clang-tidy/modernize/UseStdNumbersCheck.cpp            | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 257ede0897d71..5483e01a43dcb 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -7,20 +7,27 @@
 //===----------------------------------------------------------------------===//
 
 #include "UseStdNumbersCheck.h"
+#include "../ClangTidyDiagnosticConsumer.h"
+#include "../utils/TransformerClangTidyCheck.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/ASTMatchers/ASTMatchersInternal.h"
 #include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Basic/LLVM.h"
 #include "clang/Tooling/Transformer/RewriteRule.h"
 #include "clang/Tooling/Transformer/Stencil.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/MathExtras.h"
 #include <cstdint>
+#include <cstdlib>
 #include <string>
+#include <utility>
 
 namespace {
 using namespace clang::ast_matchers;

>From 7a66de0a0e7dd95cd5a7bdcaf376866ebae41d93 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 28 Oct 2023 11:20:48 +0200
Subject: [PATCH 19/44] rename chainedIfBound to applyRuleForBoundOrDefault

---
 .../clang-tidy/modernize/UseStdNumbersCheck.cpp           | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 5483e01a43dcb..81098e20ad85b 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -179,9 +179,9 @@ auto matchPhi() {
   return expr(anyOf(PhiFormula, matchFloatLiteralNear(llvm::numbers::phi)));
 }
 
-EditGenerator
-chainedIfBound(ASTEdit DefaultEdit,
-               llvm::SmallVector<std::pair<StringRef, ASTEdit>, 2> Edits) {
+EditGenerator applyRuleForBoundOrDefault(
+    ASTEdit DefaultEdit,
+    llvm::SmallVector<std::pair<StringRef, ASTEdit>, 2> Edits) {
   return [Edits = std::move(Edits), DefaultEdit = std::move(DefaultEdit)](
              const MatchFinder::MatchResult &Result) {
     auto &Map = Result.Nodes.getMap();
@@ -204,7 +204,7 @@ RewriteRuleWith<std::string> makeRule(const Matcher<clang::Stmt> Matcher,
   const auto LongDoubleEdit =
       changeTo(cat("std::numbers::", Constant, "_v<long double>"));
 
-  const auto EditRules = chainedIfBound(
+  const auto EditRules = applyRuleForBoundOrDefault(
       DefaultEdit, {{"float", FloatEdit}, {"long double", LongDoubleEdit}});
 
   return makeRule(

>From ec2056778f6de3e9241ac1c29a0170577d525d94 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 3 Nov 2023 03:02:30 +0100
Subject: [PATCH 20/44] add support for combinations of casts

---
 .../modernize/UseStdNumbersCheck.cpp          | 44 ++++++++++++-----
 .../checkers/modernize/use-std-numbers.cpp    | 48 +++++++++++++++++++
 2 files changed, 81 insertions(+), 11 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 81098e20ad85b..84750bd98ef50 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -55,10 +55,27 @@ AST_MATCHER_P(clang::QualType, hasCanonicalTypeUnqualified,
                               Builder);
 }
 
+AST_MATCHER(clang::QualType, isArithmetic) { return Node->isArithmeticType(); }
+AST_MATCHER(clang::QualType, isFloating) { return Node->isFloatingType(); }
+
+auto ignoreImplicitAndArithmeticCasting(const Matcher<clang::Expr> Matcher) {
+  return expr(
+      ignoringImplicit(expr(hasType(qualType(isArithmetic())),
+                            ignoringParenCasts(ignoringImplicit(Matcher)))));
+}
+
+auto ignoreImplicitAndFloatingCasting(const Matcher<clang::Expr> Matcher) {
+  return expr(
+      ignoringImplicit(expr(hasType(qualType(isFloating())),
+                            ignoringParenCasts(ignoringImplicit(Matcher)))));
+}
+
 auto matchMathCall(const StringRef FunctionName,
                    const Matcher<clang::Expr> ArgumentMatcher) {
-  return callExpr(callee(functionDecl(hasName(FunctionName))),
-                  hasArgument(0, ignoringImplicit(ArgumentMatcher)));
+  return callExpr(
+      callee(functionDecl(hasName(FunctionName),
+                          hasParameter(0, hasType(isArithmetic())))),
+      hasArgument(0, ArgumentMatcher));
 }
 
 auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
@@ -73,7 +90,7 @@ auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
 //
 // We only care about the literal if the match is for a top-level match
 auto matchFloatLiteralNear(const double Val) {
-  return expr(ignoringImplicit(floatLiteral(near(Val))));
+  return expr(ignoreImplicitAndFloatingCasting(floatLiteral(near(Val))));
 }
 
 // Used for non-top-level matchers (i.e. matchers that are used as inner
@@ -91,18 +108,22 @@ auto matchFloatValueNear(const double Val) {
   const auto Float = floatLiteral(near(Val));
 
   const auto Dref = declRefExpr(to(varDecl(
-      anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))),
+      anyOf(isConstexpr(),
+            varDecl(hasType(qualType(isConstQualified(), isArithmetic())))),
       hasInitializer(Float))));
-  return expr(ignoringImplicit(anyOf(Float, Dref)));
+  return expr(ignoreImplicitAndFloatingCasting(anyOf(Float, Dref)));
 }
 
 auto matchValue(const int64_t ValInt) {
-  const auto Int = integerLiteral(equals(ValInt));
-  const auto Float = matchFloatValueNear(static_cast<double>(ValInt));
+  const auto Int =
+      expr(ignoreImplicitAndArithmeticCasting(integerLiteral(equals(ValInt))));
+  const auto Float = expr(ignoreImplicitAndFloatingCasting(
+      matchFloatValueNear(static_cast<double>(ValInt))));
   const auto Dref = declRefExpr(to(varDecl(
-      anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))),
-      hasInitializer(expr(ignoringImplicit(anyOf(Int, Float)))))));
-  return expr(ignoringImplicit(anyOf(Int, Float, Dref)));
+      anyOf(isConstexpr(),
+            varDecl(hasType(qualType(isConstQualified(), isArithmetic())))),
+      hasInitializer(anyOf(Int, Float)))));
+  return expr(anyOf(Int, Float, Dref));
 }
 
 auto match1Div(const Matcher<clang::Expr> Match) {
@@ -208,7 +229,8 @@ RewriteRuleWith<std::string> makeRule(const Matcher<clang::Stmt> Matcher,
       DefaultEdit, {{"float", FloatEdit}, {"long double", LongDoubleEdit}});
 
   return makeRule(
-      expr(Matcher, unless(isInTemplateInstantiation()),
+      expr(ignoreImplicitAndFloatingCasting(Matcher),
+           unless(isInTemplateInstantiation()),
            hasType(qualType(hasCanonicalType(hasCanonicalTypeUnqualified(anyOf(
                qualType(asString("float")).bind("float"),
                qualType(asString("double")),
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 2ceec289ce7c1..263106b5c4ee5 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -21,6 +21,8 @@ double log10(double Arg);
 template<typename T>
 void sink(T&&) { }
 
+void floatSink(float) {}
+
 #define MY_PI 3.1415926
 
 #define INV_SQRT3 1 / bar::sqrt(3)
@@ -139,6 +141,52 @@ void foo(){
     // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: auto log2e = std::numbers::log2e;
 
+    floatSink(log2(Euler));
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+    floatSink(static_cast<float>(log2(Euler)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+    floatSink(1.4426950);
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+    floatSink(static_cast<float>(1.4426950));
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+    floatSink(log2(static_cast<float>(Euler)));
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+    floatSink(static_cast<float>(log2(static_cast<float>(Euler))));
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+    floatSink(static_cast<float>(log2(static_cast<int>(Euler))));
+
+    floatSink(static_cast<int>(log2(static_cast<float>(Euler))));
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e));
+
+    floatSink(1.4426950F);
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+    floatSink(static_cast<double>(1.4426950F));
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+    floatSink(static_cast<int>(1.4426950F));
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
+
     log10(exp(1));
     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer std::numbers math constant [modernize-use-std-numbers]

>From 019f84fd5c9beb370a26ddb65454c2e6a9cf9074 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 4 Nov 2023 00:30:21 +0100
Subject: [PATCH 21/44] check QualType::isNull in custom matchers

---
 .../clang-tidy/modernize/UseStdNumbersCheck.cpp       | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 84750bd98ef50..d981bb4c31123 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -51,12 +51,17 @@ AST_MATCHER_P(clang::FloatingLiteral, near, double, Value) {
 
 AST_MATCHER_P(clang::QualType, hasCanonicalTypeUnqualified,
               Matcher<clang::QualType>, InnerMatcher) {
-  return InnerMatcher.matches(Node->getCanonicalTypeUnqualified(), Finder,
+  return !Node.isNull() &&
+         InnerMatcher.matches(Node->getCanonicalTypeUnqualified(), Finder,
                               Builder);
 }
 
-AST_MATCHER(clang::QualType, isArithmetic) { return Node->isArithmeticType(); }
-AST_MATCHER(clang::QualType, isFloating) { return Node->isFloatingType(); }
+AST_MATCHER(clang::QualType, isArithmetic) {
+  return !Node.isNull() && Node->isArithmeticType();
+}
+AST_MATCHER(clang::QualType, isFloating) {
+  return !Node.isNull() && Node->isFloatingType();
+}
 
 auto ignoreImplicitAndArithmeticCasting(const Matcher<clang::Expr> Matcher) {
   return expr(

>From 353f330896572eecdfa96e299b17ea4c7cf276f2 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 4 Nov 2023 01:05:14 +0100
Subject: [PATCH 22/44] refactor Dref match in matchFloatValueNear

- constexpr implies const
- constrain the varDecl's type to be a floating type
- use ignoreImplicitAndFloatingCasting on the hasInitializer expression
---
 .../modernize/UseStdNumbersCheck.cpp          |  7 ++---
 .../checkers/modernize/use-std-numbers.cpp    | 28 +++++++++++++++++--
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index d981bb4c31123..2a15beb3a1ba9 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -112,10 +112,9 @@ auto matchFloatLiteralNear(const double Val) {
 auto matchFloatValueNear(const double Val) {
   const auto Float = floatLiteral(near(Val));
 
-  const auto Dref = declRefExpr(to(varDecl(
-      anyOf(isConstexpr(),
-            varDecl(hasType(qualType(isConstQualified(), isArithmetic())))),
-      hasInitializer(Float))));
+  const auto Dref = declRefExpr(
+      to(varDecl(hasType(qualType(isConstQualified(), isFloating())),
+                 hasInitializer(ignoreImplicitAndFloatingCasting(Float)))));
   return expr(ignoreImplicitAndFloatingCasting(anyOf(Float, Dref)));
 }
 
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 263106b5c4ee5..bac63edc30f21 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -15,7 +15,12 @@ namespace bar {
 
 double exp(double Arg);
 double log(double Arg);
+
 double log2(double Arg);
+float log2(float Arg);
+template <typename T>
+auto log2(T val) { return log2(static_cast<double>(val)); }
+
 double log10(double Arg);
 
 template<typename T>
@@ -27,6 +32,9 @@ void floatSink(float) {}
 
 #define INV_SQRT3 1 / bar::sqrt(3)
 
+using my_double = double;
+using my_float = float;
+
 void foo(){
     static constexpr double Pi = 3.1415926;
     // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
@@ -74,11 +82,18 @@ void foo(){
     // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
 
+    static constexpr my_double Euler5 = 2.7182818;
+    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr my_double Euler5 = std::numbers::e;
+
+    static constexpr my_float Euler6 = 2.7182818;
+    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr my_float Euler6 = std::numbers::e_v<float>;
+
     static constexpr double InvPi = 1.0 / Pi;
     // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double InvPi = std::numbers::inv_pi;
 
-    using my_float = const float;
     static constexpr my_float Actually2MyFloat = 2;
     bar::sqrt(Actually2MyFloat);
     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
@@ -137,6 +152,14 @@ void foo(){
     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
+    log2(Euler5);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::log2e;
+
+    log2(Euler6);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: std::numbers::log2e_v<float>;
+
     auto log2e = 1.4426950;
     // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: auto log2e = std::numbers::log2e;
@@ -172,7 +195,7 @@ void foo(){
 
     floatSink(static_cast<int>(log2(static_cast<float>(Euler))));
     // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-    // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e));
+    // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
 
     floatSink(1.4426950F);
     // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
@@ -303,7 +326,6 @@ void baz(){
     // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr T Phi3 = std::numbers::phi_v<long double>;
 
-    using my_float = const float;
     static constexpr my_float Actually2MyFloat = 2;
     bar::sqrt(Actually2MyFloat);
     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]

>From 70eb8e8d89ec8ee5bbcbfb74f3824a395ee01b1d Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 4 Nov 2023 01:11:31 +0100
Subject: [PATCH 23/44] change Dref match in MatchValue

- constexpr implies const
---
 .../clang-tidy/modernize/UseStdNumbersCheck.cpp            | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 2a15beb3a1ba9..ee4c530a62963 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -123,10 +123,9 @@ auto matchValue(const int64_t ValInt) {
       expr(ignoreImplicitAndArithmeticCasting(integerLiteral(equals(ValInt))));
   const auto Float = expr(ignoreImplicitAndFloatingCasting(
       matchFloatValueNear(static_cast<double>(ValInt))));
-  const auto Dref = declRefExpr(to(varDecl(
-      anyOf(isConstexpr(),
-            varDecl(hasType(qualType(isConstQualified(), isArithmetic())))),
-      hasInitializer(anyOf(Int, Float)))));
+  const auto Dref = declRefExpr(
+      to(varDecl(hasType(qualType(isConstQualified(), isArithmetic())),
+                 hasInitializer(anyOf(Int, Float)))));
   return expr(anyOf(Int, Float, Dref));
 }
 

>From 42cad98a437a9253f481da3af07f342871af1147 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 4 Nov 2023 01:14:41 +0100
Subject: [PATCH 24/44] fix implicit casts in hasInitializer of matchValue

- implicit conversiosn might occur
- allow only implicit casts to floating types
when the initializer is a float literal
- allow implicit conversions for ints
---
 .../clang-tidy/modernize/UseStdNumbersCheck.cpp            | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index ee4c530a62963..f956bd5ae153e 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -123,9 +123,10 @@ auto matchValue(const int64_t ValInt) {
       expr(ignoreImplicitAndArithmeticCasting(integerLiteral(equals(ValInt))));
   const auto Float = expr(ignoreImplicitAndFloatingCasting(
       matchFloatValueNear(static_cast<double>(ValInt))));
-  const auto Dref = declRefExpr(
-      to(varDecl(hasType(qualType(isConstQualified(), isArithmetic())),
-                 hasInitializer(anyOf(Int, Float)))));
+  const auto Dref = declRefExpr(to(varDecl(
+      hasType(qualType(isConstQualified(), isArithmetic())),
+      hasInitializer(expr(anyOf(ignoringImplicit(Int),
+                                ignoreImplicitAndFloatingCasting(Float)))))));
   return expr(anyOf(Int, Float, Dref));
 }
 

>From 71fc18226433119a178d8f4a18f6cc794234ab5e Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 4 Nov 2023 01:18:58 +0100
Subject: [PATCH 25/44] add test for int constants initialized with float

---
 .../test/clang-tidy/checkers/modernize/use-std-numbers.cpp  | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index bac63edc30f21..eca908decbbb2 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -90,6 +90,10 @@ void foo(){
     // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr my_float Euler6 = std::numbers::e_v<float>;
 
+    static constexpr int NotEuler7 = 2.7182818;
+    // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: static constexpr int NotEuler7 = std::numbers::e;
+
     static constexpr double InvPi = 1.0 / Pi;
     // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double InvPi = std::numbers::inv_pi;
@@ -160,6 +164,8 @@ void foo(){
     // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e_v<float>;
 
+    log2(NotEuler7);
+
     auto log2e = 1.4426950;
     // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer std::numbers math constant [modernize-use-std-numbers]
     // CHECK-FIXES: auto log2e = std::numbers::log2e;

>From 2fe0d0d67fcac68244a2bed865f7c0071158e2a8 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 4 Nov 2023 01:28:05 +0100
Subject: [PATCH 26/44] extend documentation

- provide the list of supported constants
- explain replacements a bit more
---
 .../checks/modernize/use-std-numbers.rst      | 32 ++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
index 8cd3149879282..e51da6575958b 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -4,15 +4,44 @@ modernize-use-std-numbers
 =========================
 
 Finds constants and function calls to math functions that can be replaced
-with c++20's mathematical constants from the ``numbers`` header and offers fix-it hints.
+with c++20's mathematical constants from the ``numbers`` header and offers
+fix-it hints.
 Does not match the use of variables with that value, and instead,
 offers a replacement at the definition of those variables.
+Function calls that match the pattern of how the constant is calculated are
+matched and replaced with the ``std::numbers`` constant.
+The use of macros gets replaced with the corresponding ``std::numbers``
+constant, instead of changing the macro definition.
+
+The following list of constants from the ``numbers`` header are supported:
+
+* e
+* log2e
+* log10e
+* pi
+* inv_pi
+* inv_sqrtpi
+* ln2
+* ln10
+* sqrt2
+* sqrt3
+* inv_sqrt3
+* egamma
+* phi
+
+The list currently includes all constants as of C++20.
+
+The replacements try to match the type of the inserted constant by how the
+removed expression was used, e.g., switching between ``std::numbers::e`` to
+``std::numbers::e_v<float>`` or ``std::numbers::e_v<long double>``
+where appropriate.
 
 .. code-block:: c++
 
     double sqrt(double);
     double log(double);
     void sink(auto&&) {}
+    void floatSink(float);
 
     #define MY_PI 3.1415926
 
@@ -25,4 +54,5 @@ offers a replacement at the definition of those variables.
         log2(Euler);      // std::numbers::log2e;
         1 / sqrt(MY_PI);  // std::numbers::inv_sqrtpi;
         sink(MY_PI);      // sink(std::numbers::pi);
+        floatSink(MY_PI); // floatSink(std::numbers::pi_v<float>);
     }

>From fd888ae7914c49ad6b3539232c9be9afc27f23db Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 10 Nov 2023 17:52:41 +0100
Subject: [PATCH 27/44] refactor from using transformer to a normal check

- change from seperated matchers to a single unified matcher
- prefer to diagnose patterns (formulas) before literals,
  diagnosing the expr with the largest possible impact/fixit
- the numbers constant that is the closest match to the matched literal
  is offered as a replacement, instead of the first one found.
- explicitly mention the constant that the fix-it is offering
---
 .../modernize/UseStdNumbersCheck.cpp          | 352 ++++++++++++------
 .../clang-tidy/modernize/UseStdNumbersCheck.h |  15 +-
 .../checkers/modernize/use-std-numbers.cpp    | 198 +++++-----
 3 files changed, 353 insertions(+), 212 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index f956bd5ae153e..a405947e7f872 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -8,7 +8,6 @@
 
 #include "UseStdNumbersCheck.h"
 #include "../ClangTidyDiagnosticConsumer.h"
-#include "../utils/TransformerClangTidyCheck.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
@@ -18,29 +17,28 @@
 #include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/ASTMatchers/ASTMatchersInternal.h"
 #include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/LLVM.h"
-#include "clang/Tooling/Transformer/RewriteRule.h"
-#include "clang/Tooling/Transformer/Stencil.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/MathExtras.h"
+#include <array>
 #include <cstdint>
 #include <cstdlib>
+#include <initializer_list>
 #include <string>
+#include <tuple>
 #include <utility>
 
 namespace {
 using namespace clang::ast_matchers;
 using clang::ast_matchers::internal::Matcher;
-using clang::transformer::addInclude;
-using clang::transformer::applyFirst;
-using clang::transformer::ASTEdit;
-using clang::transformer::cat;
-using clang::transformer::changeTo;
-using clang::transformer::edit;
-using clang::transformer::EditGenerator;
-using clang::transformer::flattenVector;
-using clang::transformer::RewriteRuleWith;
 using llvm::StringRef;
 
 constexpr auto DiffThreshold = 0.001;
@@ -63,6 +61,19 @@ AST_MATCHER(clang::QualType, isFloating) {
   return !Node.isNull() && Node->isFloatingType();
 }
 
+AST_MATCHER_P(clang::Expr, anyOfExhaustive,
+              llvm::ArrayRef<Matcher<clang::Stmt>>, Exprs) {
+  bool FoundMatch = false;
+  for (const auto &InnerMatcher : Exprs) {
+    clang::ast_matchers::internal::BoundNodesTreeBuilder Result = *Builder;
+    if (InnerMatcher.matches(Node, Finder, &Result)) {
+      *Builder = std::move(Result);
+      FoundMatch = true;
+    }
+  }
+  return FoundMatch;
+}
+
 auto ignoreImplicitAndArithmeticCasting(const Matcher<clang::Expr> Matcher) {
   return expr(
       ignoringImplicit(expr(hasType(qualType(isArithmetic())),
@@ -77,10 +88,10 @@ auto ignoreImplicitAndFloatingCasting(const Matcher<clang::Expr> Matcher) {
 
 auto matchMathCall(const StringRef FunctionName,
                    const Matcher<clang::Expr> ArgumentMatcher) {
-  return callExpr(
-      callee(functionDecl(hasName(FunctionName),
-                          hasParameter(0, hasType(isArithmetic())))),
-      hasArgument(0, ArgumentMatcher));
+  return expr(ignoreImplicitAndFloatingCasting(
+      callExpr(callee(functionDecl(hasName(FunctionName),
+                                   hasParameter(0, hasType(isArithmetic())))),
+               hasArgument(0, ArgumentMatcher))));
 }
 
 auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
@@ -93,9 +104,10 @@ auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
 // E.g. The matcher of `std::numbers::pi` uses this matcher to look to
 // floatLiterals that have the value of pi.
 //
-// We only care about the literal if the match is for a top-level match
-auto matchFloatLiteralNear(const double Val) {
-  return expr(ignoreImplicitAndFloatingCasting(floatLiteral(near(Val))));
+// If the match is for a top-level match, we only care about the literal.
+auto matchFloatLiteralNear(const StringRef Constant, const double Val) {
+  return expr(
+      ignoreImplicitAndFloatingCasting(floatLiteral(near(Val)).bind(Constant)));
 }
 
 // Used for non-top-level matchers (i.e. matchers that are used as inner
@@ -140,58 +152,85 @@ auto matchEuler() {
                     matchMathCall("exp", matchValue(1))));
 }
 auto matchEulerTopLevel() {
-  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::e),
-                    matchMathCall("exp", matchValue(1))));
+  return expr(anyOf(matchFloatLiteralNear("e_literal", llvm::numbers::e),
+                    matchMathCall("exp", matchValue(1)).bind("e_pattern")))
+      .bind("e");
 }
 
 auto matchLog2Euler() {
-  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::log2e),
-                    matchMathCall("log2", matchEuler())));
+  return expr(
+             anyOf(matchFloatLiteralNear("log2e_literal", llvm::numbers::log2e),
+                   matchMathCall("log2", matchEuler()).bind("log2e_pattern")))
+      .bind("log2e");
 }
 
 auto matchLog10Euler() {
-  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::log10e),
-                    matchMathCall("log10", matchEuler())));
+  return expr(
+             anyOf(
+                 matchFloatLiteralNear("log10e_literal", llvm::numbers::log10e),
+                 matchMathCall("log10", matchEuler()).bind("log10e_pattern")))
+      .bind("log10e");
 }
 
 auto matchPi() { return matchFloatValueNear(llvm::numbers::pi); }
-auto matchPiTopLevel() { return matchFloatLiteralNear(llvm::numbers::pi); }
+auto matchPiTopLevel() {
+  return matchFloatLiteralNear("pi_literal", llvm::numbers::pi).bind("pi");
+}
 
-auto matchEgamma() { return matchFloatLiteralNear(llvm::numbers::egamma); }
+auto matchEgamma() {
+  return matchFloatLiteralNear("egamma_literal", llvm::numbers::egamma)
+      .bind("egamma");
+}
 
 auto matchInvPi() {
-  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::inv_pi),
-                    match1Div(matchPi())));
+  return expr(anyOf(matchFloatLiteralNear("inv_pi_literal",
+                                          llvm::numbers::inv_pi),
+                    match1Div(matchPi()).bind("inv_pi_pattern")))
+      .bind("inv_pi");
 }
 
 auto matchInvSqrtPi() {
-  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::inv_sqrtpi),
-                    match1Div(matchSqrt(matchPi()))));
+  return expr(anyOf(matchFloatLiteralNear("inv_sqrtpi_literal",
+                                          llvm::numbers::inv_sqrtpi),
+                    match1Div(matchSqrt(matchPi())).bind("inv_sqrtpi_pattern")))
+      .bind("inv_sqrtpi");
 }
 
 auto matchLn2() {
-  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::ln2),
-                    matchMathCall("log", ignoringImplicit(matchValue(2)))));
+  return expr(anyOf(matchFloatLiteralNear("ln2_literal", llvm::numbers::ln2),
+                    matchMathCall("log", ignoringImplicit(matchValue(2)))
+                        .bind("ln2_pattern")))
+      .bind("ln2");
 }
 
 auto machterLn10() {
-  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::ln10),
-                    matchMathCall("log", ignoringImplicit(matchValue(10)))));
+  return expr(anyOf(matchFloatLiteralNear("ln10_literal", llvm::numbers::ln10),
+                    matchMathCall("log", ignoringImplicit(matchValue(10)))
+                        .bind("ln10_pattern")))
+      .bind("ln10");
 }
 
 auto matchSqrt2() {
-  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::sqrt2),
-                    matchSqrt(matchValue(2))));
+  return expr(
+             anyOf(matchFloatLiteralNear("sqrt2_literal", llvm::numbers::sqrt2),
+                   matchSqrt(matchValue(2)).bind("sqrt2_pattern")))
+      .bind("sqrt2");
 }
 
 auto matchSqrt3() {
-  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::sqrt3),
-                    matchSqrt(matchValue(3))));
+  return expr(
+             anyOf(matchFloatLiteralNear("sqrt3_literal", llvm::numbers::sqrt3),
+                   matchSqrt(matchValue(3)).bind("sqrt3_pattern")))
+      .bind("sqrt3");
 }
 
 auto matchInvSqrt3() {
-  return expr(anyOf(matchFloatLiteralNear(llvm::numbers::inv_sqrt3),
-                    match1Div(matchSqrt(matchValue(3)))));
+  return expr(
+             anyOf(
+                 matchFloatLiteralNear("inv_sqrt3_literal",
+                                       llvm::numbers::inv_sqrt3),
+                 match1Div(matchSqrt(matchValue(3))).bind("inv_sqrt3_pattern")))
+      .bind("inv_sqrt3");
 }
 
 auto matchPhi() {
@@ -201,88 +240,179 @@ auto matchPhi() {
           hasOperatorName("+"), hasEitherOperand(matchValue(1)),
           hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
       hasRHS(matchValue(2)));
-  return expr(anyOf(PhiFormula, matchFloatLiteralNear(llvm::numbers::phi)));
-}
-
-EditGenerator applyRuleForBoundOrDefault(
-    ASTEdit DefaultEdit,
-    llvm::SmallVector<std::pair<StringRef, ASTEdit>, 2> Edits) {
-  return [Edits = std::move(Edits), DefaultEdit = std::move(DefaultEdit)](
-             const MatchFinder::MatchResult &Result) {
-    auto &Map = Result.Nodes.getMap();
-    for (const auto &[Id, EditOfId] : Edits) {
-      if (Map.find(Id) != Map.end()) {
-        return edit(EditOfId)(Result);
-      }
-    }
-    return edit(DefaultEdit)(Result);
-  };
+  return expr(anyOf(PhiFormula.bind("phi_pattern"),
+                    matchFloatLiteralNear("phi_literal", llvm::numbers::phi)))
+      .bind("phi");
 }
 
-RewriteRuleWith<std::string> makeRule(const Matcher<clang::Stmt> Matcher,
-                                      const StringRef Constant) {
-  static const auto AddNumbersInclude =
-      addInclude("numbers", clang::transformer::IncludeFormat::Angled);
+std::string getCode(const StringRef Constant, const bool IsFloat,
+                    const bool IsLongDouble) {
+  if (IsFloat) {
+    return ("std::numbers::" + Constant + "_v<float>").str();
+  }
+  if (IsLongDouble) {
+    return ("std::numbers::" + Constant + "_v<long double>").str();
+  }
+  return ("std::numbers::" + Constant).str();
+}
 
-  const auto DefaultEdit = changeTo(cat("std::numbers::", Constant));
-  const auto FloatEdit = changeTo(cat("std::numbers::", Constant, "_v<float>"));
-  const auto LongDoubleEdit =
-      changeTo(cat("std::numbers::", Constant, "_v<long double>"));
+bool isRangeOfCompleteMacro(const clang::SourceRange &Range,
+                            const clang::SourceManager &SM,
+                            const clang::LangOptions &LO) {
+  if (!Range.getBegin().isMacroID()) {
+    return false;
+  }
+  if (!clang::Lexer::isAtStartOfMacroExpansion(Range.getBegin(), SM, LO)) {
+    return false;
+  }
+
+  if (!Range.getEnd().isMacroID()) {
+    return false;
+  }
+
+  if (!clang::Lexer::isAtEndOfMacroExpansion(Range.getEnd(), SM, LO)) {
+    return false;
+  }
+
+  return true;
+}
 
-  const auto EditRules = applyRuleForBoundOrDefault(
-      DefaultEdit, {{"float", FloatEdit}, {"long double", LongDoubleEdit}});
+} // namespace
 
-  return makeRule(
-      expr(ignoreImplicitAndFloatingCasting(Matcher),
+namespace clang::tidy::modernize {
+UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name,
+                                       ClangTidyContext *const Context)
+    : ClangTidyCheck(Name, Context),
+      IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+                                               utils::IncludeSorter::IS_LLVM),
+                      areDiagsSelfContained()) {}
+
+void UseStdNumbersCheck::registerMatchers(MatchFinder *Finder) {
+  static const auto ConstantMatchers = {
+      matchLog2Euler(), matchLog10Euler(), matchEulerTopLevel(), matchEgamma(),
+      matchInvSqrtPi(), matchInvPi(),      matchPiTopLevel(),    matchLn2(),
+      machterLn10(),    matchSqrt2(),      matchInvSqrt3(),      matchSqrt3(),
+      matchPhi(),
+  };
+
+  Finder->addMatcher(
+      expr(anyOfExhaustive(ConstantMatchers),
            unless(isInTemplateInstantiation()),
+           unless(hasParent(expr(
+               anyOf(implicitCastExpr(hasImplicitDestinationType(isFloating())),
+                     explicitCastExpr(hasDestinationType(isFloating())))))),
            hasType(qualType(hasCanonicalType(hasCanonicalTypeUnqualified(anyOf(
                qualType(asString("float")).bind("float"),
                qualType(asString("double")),
                qualType(asString("long double")).bind("long double"))))))),
-      flattenVector({edit(AddNumbersInclude), EditRules}),
-      cat("prefer std::numbers math constant"));
-}
-
-/*
-  List of all math constants
-  + e
-  + log2e
-  + log10e
-  + pi
-  + inv_pi
-  + inv_sqrtpi
-  + ln2
-  + ln10
-  + sqrt2
-  + sqrt3
-  + inv_sqrt3
-  + egamma
-  + phi
-*/
-
-RewriteRuleWith<std::string> makeRewriteRule() {
-  return applyFirst({
-      makeRule(matchLog2Euler(), "log2e"),
-      makeRule(matchLog10Euler(), "log10e"),
-      makeRule(matchEulerTopLevel(), "e"),
-      makeRule(matchEgamma(), "egamma"),
-      makeRule(matchInvSqrtPi(), "inv_sqrtpi"),
-      makeRule(matchInvPi(), "inv_pi"),
-      makeRule(matchPiTopLevel(), "pi"),
-      makeRule(matchLn2(), "ln2"),
-      makeRule(machterLn10(), "ln10"),
-      makeRule(matchSqrt2(), "sqrt2"),
-      makeRule(matchInvSqrt3(), "inv_sqrt3"),
-      makeRule(matchSqrt3(), "sqrt3"),
-      makeRule(matchPhi(), "phi"),
+      this);
+}
+
+void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
+  /*
+    List of all math constants in the `<numbers>` header
+    + e
+    + log2e
+    + log10e
+    + pi
+    + inv_pi
+    + inv_sqrtpi
+    + ln2
+    + ln10
+    + sqrt2
+    + sqrt3
+    + inv_sqrt3
+    + egamma
+    + phi
+  */
+
+  // The ordering determines what constants are looked at first.
+  // E.g. look at 'inv_sqrt3' before 'sqrt3' to be able to replace the larger
+  // expression
+  constexpr auto Constants = std::array<std::pair<StringRef, double>, 13>{
+      std::pair{StringRef{"log2e"}, llvm::numbers::log2e},
+      std::pair{StringRef{"log10e"}, llvm::numbers::log10e},
+      std::pair{StringRef{"e"}, llvm::numbers::e},
+      std::pair{StringRef{"egamma"}, llvm::numbers::egamma},
+      std::pair{StringRef{"inv_sqrtpi"}, llvm::numbers::inv_sqrtpi},
+      std::pair{StringRef{"inv_pi"}, llvm::numbers::inv_pi},
+      std::pair{StringRef{"pi"}, llvm::numbers::pi},
+      std::pair{StringRef{"ln2"}, llvm::numbers::ln2},
+      std::pair{StringRef{"ln10"}, llvm::numbers::ln10},
+      std::pair{StringRef{"sqrt2"}, llvm::numbers::sqrt2},
+      std::pair{StringRef{"inv_sqrt3"}, llvm::numbers::inv_sqrt3},
+      std::pair{StringRef{"sqrt3"}, llvm::numbers::sqrt3},
+      std::pair{StringRef{"phi"}, llvm::numbers::phi},
+  };
+
+  auto MatchedLiterals =
+      llvm::SmallVector<std::tuple<std::string, double, const Expr *>>{};
+
+  const auto &SM = *Result.SourceManager;
+  const auto &LO = Result.Context->getLangOpts();
+
+  const auto IsFloat = Result.Nodes.getNodeAs<QualType>("float") != nullptr;
+  const auto IsLongDouble =
+      Result.Nodes.getNodeAs<QualType>("long double") != nullptr;
+
+  for (const auto &[ConstantName, ConstantValue] : Constants) {
+    const auto *const Match = Result.Nodes.getNodeAs<Expr>(ConstantName);
+    if (Match == nullptr) {
+      continue;
+    }
+
+    const auto Range = Match->getSourceRange();
+
+    if (Range.getBegin().isMacroID() &&
+        !isRangeOfCompleteMacro(Range, SM, LO)) {
+      continue;
+    }
+
+    const auto PatternBindString = (ConstantName + "_pattern").str();
+    if (Result.Nodes.getNodeAs<Expr>(PatternBindString) != nullptr) {
+      const auto Code = getCode(ConstantName, IsFloat, IsLongDouble);
+      diag(Range.getBegin(), "prefer '%0' math constant")
+          << Code << FixItHint::CreateReplacement(Range, Code);
+      return;
+    }
+
+    const auto LiteralBindString = (ConstantName + "_literal").str();
+    if (const auto *const Literal =
+            Result.Nodes.getNodeAs<FloatingLiteral>(LiteralBindString)) {
+      MatchedLiterals.emplace_back(
+          ConstantName,
+          std::abs(Literal->getValueAsApproximateDouble() - ConstantValue),
+          Match);
+    }
+  }
+
+  // We may have had no matches with literals, but a match with a pattern that
+  // was a subexpression of a macro which was therefore skipped.
+  if (MatchedLiterals.empty()) {
+    return;
+  }
+
+  llvm::sort(MatchedLiterals, [](const auto &LHS, const auto &RHS) {
+    return std::get<1>(LHS) < std::get<1>(RHS);
   });
+
+  const auto &[Constant, _, Node] = MatchedLiterals.front();
+
+  const auto Range = Node->getSourceRange();
+  if (Range.getBegin().isMacroID() && !isRangeOfCompleteMacro(Range, SM, LO)) {
+    return;
+  }
+
+  const auto Code = getCode(Constant, IsFloat, IsLongDouble);
+  diag(Range.getBegin(), "prefer '%0' math constant")
+      << Code << FixItHint::CreateReplacement(Range, Code)
+      << IncludeInserter.createIncludeInsertion(
+             Result.SourceManager->getFileID(Range.getBegin()), "<numbers>");
 }
-} // namespace
 
-namespace clang::tidy::modernize {
-UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name,
-                                       ClangTidyContext *const Context)
-    : TransformerClangTidyCheck(Name, Context) {
-  setRule(makeRewriteRule());
+void UseStdNumbersCheck::registerPPCallbacks(const SourceManager &SM,
+                                             Preprocessor *PP,
+                                             Preprocessor *ModuleExpanderPP) {
+  IncludeInserter.registerPreprocessor(PP);
 }
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
index 3cf2d9244cc81..da52f2b9ab4ce 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
@@ -9,7 +9,8 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDNUMBERSCHECK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDNUMBERSCHECK_H
 
-#include "../utils/TransformerClangTidyCheck.h"
+#include "../ClangTidyCheck.h"
+#include "../utils/IncludeInserter.h"
 
 namespace clang::tidy::modernize {
 
@@ -21,13 +22,23 @@ namespace clang::tidy::modernize {
 ///
 /// For the user-facing documentation see:
 /// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-numbers.html
-class UseStdNumbersCheck : public utils::TransformerClangTidyCheck {
+class UseStdNumbersCheck : public ClangTidyCheck {
 public:
   UseStdNumbersCheck(StringRef Name, ClangTidyContext *Context);
 
   bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
     return LangOpts.CPlusPlus20;
   }
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override {
+    Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+  }
+
+private:
+  utils::IncludeInserter IncludeInserter;
 };
 
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index eca908decbbb2..c979d8e06efa2 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -9,7 +9,7 @@ namespace bar {
     auto sqrt(T val) { return sqrt(static_cast<double>(val)); }
 
     static constexpr double e = 2.718281828459045235360287471352662497757247093;
-    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double e = std::numbers::e;
 }
 
@@ -37,20 +37,20 @@ using my_float = float;
 
 void foo(){
     static constexpr double Pi = 3.1415926;
-    // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Pi = std::numbers::pi;
 
     static constexpr double Euler = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Euler = std::numbers::e;
 
     static constexpr double Phi = 1.6180339;
-    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Phi = std::numbers::phi;
 
     static constexpr double PiCopy = Pi;
     static constexpr double PiDefineFromMacro = MY_PI;
-    // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double PiDefineFromMacro = std::numbers::pi;
 
     // not close enough to match value (DiffThreshold)
@@ -59,67 +59,67 @@ void foo(){
     static constexpr double Phi2 = 1.61;
 
     static constexpr double Pi3 = 3.1415926L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Pi3 = std::numbers::pi;
 
     static constexpr double Euler3 = 2.7182818L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Euler3 = std::numbers::e;
 
     static constexpr double Phi3 = 1.6180339L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Phi3 = std::numbers::phi;
 
     static constexpr long double Pi4 = 3.1415926L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::pi_v<long double>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr long double Pi4 = std::numbers::pi_v<long double>;
 
     static constexpr long double Euler4 = 2.7182818L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer 'std::numbers::e_v<long double>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr long double Euler4 = std::numbers::e_v<long double>;
 
     static constexpr long double Phi4 = 1.6180339L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::phi_v<long double>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
 
     static constexpr my_double Euler5 = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr my_double Euler5 = std::numbers::e;
 
     static constexpr my_float Euler6 = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::e_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr my_float Euler6 = std::numbers::e_v<float>;
 
     static constexpr int NotEuler7 = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr int NotEuler7 = std::numbers::e;
 
     static constexpr double InvPi = 1.0 / Pi;
-    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::inv_pi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double InvPi = std::numbers::inv_pi;
 
     static constexpr my_float Actually2MyFloat = 2;
     bar::sqrt(Actually2MyFloat);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2_v<float>;
 
     sink(MY_PI);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::pi);
 
     constexpr static auto One = 1;
     constexpr static auto Two = 2;
 
     bar::sqrt(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     bar::sqrt(Two);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     bar::sqrt(2.0);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     auto Not2 = 2;
@@ -128,169 +128,169 @@ void foo(){
 
     const auto Actually2 = 2;
     bar::sqrt(Actually2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     exp(1);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::e;
 
     exp(One);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::e;
 
     exp(1.00000000000001);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::e;
 
     log2(exp(1));
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
     log2(Euler);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
     log2(bar::e);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
     log2(Euler5);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
     log2(Euler6);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e_v<float>;
 
     log2(NotEuler7);
 
     auto log2e = 1.4426950;
-    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: auto log2e = std::numbers::log2e;
 
     floatSink(log2(Euler));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<float>(log2(Euler)));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(1.4426950);
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<float>(1.4426950));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(log2(static_cast<float>(Euler)));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<float>(log2(static_cast<float>(Euler))));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<float>(log2(static_cast<int>(Euler))));
 
     floatSink(static_cast<int>(log2(static_cast<float>(Euler))));
-    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
 
     floatSink(1.4426950F);
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<double>(1.4426950F));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<int>(1.4426950F));
-    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
 
     log10(exp(1));
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log10e;
 
     log10(Euler);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log10e;
 
     log10(bar::e);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log10e;
 
     auto log10e = .434294;
-    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: auto log10e = std::numbers::log10e;
 
     auto egamma = 0.5772156 * 42;
-    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::egamma' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: auto egamma = std::numbers::egamma * 42;
 
     sink(InvPi);
 
     sink(1 / Pi);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_pi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_pi);
 
     sink(1 / bar::sqrt(Pi));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
 
     sink(1 / bar::sqrt(MY_PI));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
 
     log(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::ln2;
 
     log(10);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::ln10;
 
     bar::sqrt(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     sink(1 / bar::sqrt(3));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
 
     sink(INV_SQRT3);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
 
+    const auto inv_sqrt3f = .577350269F;
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::inv_sqrt3_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: const auto inv_sqrt3f = std::numbers::inv_sqrt3_v<float>;
+
     bar::sqrt(3);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt3;
 
-    auto phi = 1.6180339;
-    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-    // CHECK-FIXES: auto phi = std::numbers::phi;
+    auto somePhi = 1.6180339;
+    // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+    // CHECK-FIXES: auto somePhi = std::numbers::phi;
 
     sink(Phi);
 
     sink((42 + bar::sqrt(5)) / 2);
 
     sink((1 + bar::sqrt(5)) / 2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::phi);
 
     sink((bar::sqrt(5.0F) + 1) / 2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::phi_v<float>);
 }
 
@@ -299,20 +299,20 @@ void foo(){
 template <typename T>
 void baz(){
     static constexpr T Pi = 3.1415926;
-    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr T Pi = std::numbers::pi;
 
     static constexpr T Euler = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr T Euler = std::numbers::e;
 
     static constexpr T Phi = 1.6180339;
-    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr T Phi = std::numbers::phi;
 
     static constexpr T PiCopy = Pi;
     static constexpr T PiDefineFromMacro = MY_PI;
-    // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr T PiDefineFromMacro = std::numbers::pi;
 
     // not close enough to match value (DiffThreshold)
@@ -321,33 +321,33 @@ void baz(){
     static constexpr T Phi2 = 1.61;
 
     static constexpr T Pi3 = 3.1415926L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::pi_v<long double>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr T Pi3 = std::numbers::pi_v<long double>;
 
     static constexpr T Euler3 = 2.7182818L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e_v<long double>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr T Euler3 = std::numbers::e_v<long double>;
 
     static constexpr T Phi3 = 1.6180339L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer 'std::numbers::phi_v<long double>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr T Phi3 = std::numbers::phi_v<long double>;
 
     static constexpr my_float Actually2MyFloat = 2;
     bar::sqrt(Actually2MyFloat);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2_v<float>;
 
     constexpr static T One = 1;
     constexpr static T Two = 2;
 
     bar::sqrt(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     bar::sqrt(Two);
 
     bar::sqrt(2.0);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     T Not2 = 2;
@@ -358,47 +358,47 @@ void baz(){
     bar::sqrt(Actually2);
 
     exp(1);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::e;
 
     exp(One);
 
     exp(1.00000000000001);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::e;
 
     log2(exp(1));
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
     log2(Euler);
 
     log2(bar::e);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
     T log2e = 1.4426950;
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: T log2e = std::numbers::log2e;
 
     log10(exp(1));
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log10e;
 
     log10(Euler);
 
     log10(bar::e);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log10e;
 
     T log10e = .434294;
-    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: T log10e = std::numbers::log10e;
 
     T egamma = 0.5772156 * 42;
-    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::egamma' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: T egamma = std::numbers::egamma * 42;
 
     sink(1 / Pi);
@@ -406,44 +406,44 @@ void baz(){
     sink(1 / bar::sqrt(Pi));
 
     sink(1 / bar::sqrt(MY_PI));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
 
 
     log(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::ln2;
 
     log(10);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::ln10;
 
     bar::sqrt(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     sink(1 / bar::sqrt(3));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
 
     bar::sqrt(3);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt3;
 
     T phi = 1.6180339;
-    // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: T phi = std::numbers::phi;
 
     sink((42 + bar::sqrt(5)) / 2);
 
     sink((1 + bar::sqrt(5)) / 2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::phi);
 
     sink((bar::sqrt(5.0F) + 1) / 2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' math constant [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::phi_v<float>);
 }
 

>From 95cee0f9aa4d8fc4fcdca6c3577cb2b1ccc1f5c8 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 10 Nov 2023 22:51:28 +0100
Subject: [PATCH 28/44] change message to include what is being replaced and
 how far off literals are

---
 .../modernize/UseStdNumbersCheck.cpp          |  20 +-
 .../checkers/modernize/use-std-numbers.cpp    | 188 +++++++++---------
 2 files changed, 106 insertions(+), 102 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index a405947e7f872..cb7579d42a33c 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -27,6 +27,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/MathExtras.h"
 #include <array>
 #include <cstdint>
@@ -363,16 +364,16 @@ void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
 
     const auto Range = Match->getSourceRange();
 
-    if (Range.getBegin().isMacroID() &&
-        !isRangeOfCompleteMacro(Range, SM, LO)) {
+    const auto IsMacro = Range.getBegin().isMacroID();
+    if (IsMacro && !isRangeOfCompleteMacro(Range, SM, LO)) {
       continue;
     }
 
     const auto PatternBindString = (ConstantName + "_pattern").str();
     if (Result.Nodes.getNodeAs<Expr>(PatternBindString) != nullptr) {
       const auto Code = getCode(ConstantName, IsFloat, IsLongDouble);
-      diag(Range.getBegin(), "prefer '%0' math constant")
-          << Code << FixItHint::CreateReplacement(Range, Code);
+      diag(Range.getBegin(), "prefer '%0' to this %select{formula|macro}1")
+          << Code << IsMacro << FixItHint::CreateReplacement(Range, Code);
       return;
     }
 
@@ -396,16 +397,19 @@ void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
     return std::get<1>(LHS) < std::get<1>(RHS);
   });
 
-  const auto &[Constant, _, Node] = MatchedLiterals.front();
+  const auto &[Constant, Diff, Node] = MatchedLiterals.front();
 
   const auto Range = Node->getSourceRange();
-  if (Range.getBegin().isMacroID() && !isRangeOfCompleteMacro(Range, SM, LO)) {
+  const auto IsMacro = Range.getBegin().isMacroID();
+  if (IsMacro && !isRangeOfCompleteMacro(Range, SM, LO)) {
     return;
   }
 
   const auto Code = getCode(Constant, IsFloat, IsLongDouble);
-  diag(Range.getBegin(), "prefer '%0' math constant")
-      << Code << FixItHint::CreateReplacement(Range, Code)
+  diag(Range.getBegin(),
+       "prefer '%0' to this %select{literal|macro}1, differs by '%2'")
+      << Code << IsMacro << llvm::formatv("{0:e2}", Diff).str()
+      << FixItHint::CreateReplacement(Range, Code)
       << IncludeInserter.createIncludeInsertion(
              Result.SourceManager->getFileID(Range.getBegin()), "<numbers>");
 }
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index c979d8e06efa2..71f01ffaeb8df 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -9,7 +9,7 @@ namespace bar {
     auto sqrt(T val) { return sqrt(static_cast<double>(val)); }
 
     static constexpr double e = 2.718281828459045235360287471352662497757247093;
-    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e' to this literal, differs by '0.00e+00' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double e = std::numbers::e;
 }
 
@@ -37,20 +37,20 @@ using my_float = float;
 
 void foo(){
     static constexpr double Pi = 3.1415926;
-    // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Pi = std::numbers::pi;
 
     static constexpr double Euler = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Euler = std::numbers::e;
 
     static constexpr double Phi = 1.6180339;
-    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Phi = std::numbers::phi;
 
     static constexpr double PiCopy = Pi;
     static constexpr double PiDefineFromMacro = MY_PI;
-    // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double PiDefineFromMacro = std::numbers::pi;
 
     // not close enough to match value (DiffThreshold)
@@ -59,67 +59,67 @@ void foo(){
     static constexpr double Phi2 = 1.61;
 
     static constexpr double Pi3 = 3.1415926L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Pi3 = std::numbers::pi;
 
     static constexpr double Euler3 = 2.7182818L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Euler3 = std::numbers::e;
 
     static constexpr double Phi3 = 1.6180339L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double Phi3 = std::numbers::phi;
 
     static constexpr long double Pi4 = 3.1415926L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::pi_v<long double>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr long double Pi4 = std::numbers::pi_v<long double>;
 
     static constexpr long double Euler4 = 2.7182818L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer 'std::numbers::e_v<long double>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer 'std::numbers::e_v<long double>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr long double Euler4 = std::numbers::e_v<long double>;
 
     static constexpr long double Phi4 = 1.6180339L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::phi_v<long double>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::phi_v<long double>' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
 
     static constexpr my_double Euler5 = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr my_double Euler5 = std::numbers::e;
 
     static constexpr my_float Euler6 = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::e_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::e_v<float>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr my_float Euler6 = std::numbers::e_v<float>;
 
     static constexpr int NotEuler7 = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr int NotEuler7 = std::numbers::e;
 
     static constexpr double InvPi = 1.0 / Pi;
-    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::inv_pi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::inv_pi'  to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr double InvPi = std::numbers::inv_pi;
 
     static constexpr my_float Actually2MyFloat = 2;
     bar::sqrt(Actually2MyFloat);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>'  to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2_v<float>;
 
     sink(MY_PI);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::pi);
 
     constexpr static auto One = 1;
     constexpr static auto Two = 2;
 
     bar::sqrt(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     bar::sqrt(Two);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     bar::sqrt(2.0);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     auto Not2 = 2;
@@ -128,157 +128,157 @@ void foo(){
 
     const auto Actually2 = 2;
     bar::sqrt(Actually2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     exp(1);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::e;
 
     exp(One);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::e;
 
     exp(1.00000000000001);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::e;
 
     log2(exp(1));
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
     log2(Euler);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
     log2(bar::e);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
     log2(Euler5);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
     log2(Euler6);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e_v<float>;
 
     log2(NotEuler7);
 
     auto log2e = 1.4426950;
-    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer 'std::numbers::log2e' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: auto log2e = std::numbers::log2e;
 
     floatSink(log2(Euler));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<float>(log2(Euler)));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(1.4426950);
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<float>(1.4426950));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(log2(static_cast<float>(Euler)));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<float>(log2(static_cast<float>(Euler))));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<float>(log2(static_cast<int>(Euler))));
 
     floatSink(static_cast<int>(log2(static_cast<float>(Euler))));
-    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
 
     floatSink(1.4426950F);
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<double>(1.4426950F));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<int>(1.4426950F));
-    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
 
     log10(exp(1));
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log10e;
 
     log10(Euler);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log10e;
 
     log10(bar::e);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log10e;
 
     auto log10e = .434294;
-    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::log10e' to this literal, differs by '4.82e-07' [modernize-use-std-numbers]
     // CHECK-FIXES: auto log10e = std::numbers::log10e;
 
     auto egamma = 0.5772156 * 42;
-    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::egamma' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::egamma' to this literal, differs by '6.49e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: auto egamma = std::numbers::egamma * 42;
 
     sink(InvPi);
 
     sink(1 / Pi);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_pi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_pi' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_pi);
 
     sink(1 / bar::sqrt(Pi));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
 
     sink(1 / bar::sqrt(MY_PI));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
 
     log(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::ln2;
 
     log(10);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::ln10;
 
     bar::sqrt(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     sink(1 / bar::sqrt(3));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
 
     sink(INV_SQRT3);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this macro [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
 
     const auto inv_sqrt3f = .577350269F;
-    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::inv_sqrt3_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::inv_sqrt3_v<float>' to this literal, differs by '1.04e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: const auto inv_sqrt3f = std::numbers::inv_sqrt3_v<float>;
 
     bar::sqrt(3);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt3;
 
     auto somePhi = 1.6180339;
-    // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: auto somePhi = std::numbers::phi;
 
     sink(Phi);
@@ -286,11 +286,11 @@ void foo(){
     sink((42 + bar::sqrt(5)) / 2);
 
     sink((1 + bar::sqrt(5)) / 2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::phi);
 
     sink((bar::sqrt(5.0F) + 1) / 2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::phi_v<float>);
 }
 
@@ -299,20 +299,20 @@ void foo(){
 template <typename T>
 void baz(){
     static constexpr T Pi = 3.1415926;
-    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr T Pi = std::numbers::pi;
 
     static constexpr T Euler = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr T Euler = std::numbers::e;
 
     static constexpr T Phi = 1.6180339;
-    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr T Phi = std::numbers::phi;
 
     static constexpr T PiCopy = Pi;
     static constexpr T PiDefineFromMacro = MY_PI;
-    // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr T PiDefineFromMacro = std::numbers::pi;
 
     // not close enough to match value (DiffThreshold)
@@ -321,33 +321,33 @@ void baz(){
     static constexpr T Phi2 = 1.61;
 
     static constexpr T Pi3 = 3.1415926L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::pi_v<long double>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr T Pi3 = std::numbers::pi_v<long double>;
 
     static constexpr T Euler3 = 2.7182818L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e_v<long double>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e_v<long double>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr T Euler3 = std::numbers::e_v<long double>;
 
     static constexpr T Phi3 = 1.6180339L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer 'std::numbers::phi_v<long double>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer 'std::numbers::phi_v<long double>' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: static constexpr T Phi3 = std::numbers::phi_v<long double>;
 
     static constexpr my_float Actually2MyFloat = 2;
     bar::sqrt(Actually2MyFloat);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2_v<float>;
 
     constexpr static T One = 1;
     constexpr static T Two = 2;
 
     bar::sqrt(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     bar::sqrt(Two);
 
     bar::sqrt(2.0);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     T Not2 = 2;
@@ -358,47 +358,47 @@ void baz(){
     bar::sqrt(Actually2);
 
     exp(1);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::e;
 
     exp(One);
 
     exp(1.00000000000001);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::e;
 
     log2(exp(1));
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
     log2(Euler);
 
     log2(bar::e);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log2e;
 
     T log2e = 1.4426950;
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: T log2e = std::numbers::log2e;
 
     log10(exp(1));
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log10e;
 
     log10(Euler);
 
     log10(bar::e);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::log10e;
 
     T log10e = .434294;
-    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::log10e' to this literal, differs by '4.82e-07' [modernize-use-std-numbers]
     // CHECK-FIXES: T log10e = std::numbers::log10e;
 
     T egamma = 0.5772156 * 42;
-    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::egamma' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::egamma' to this literal, differs by '6.49e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: T egamma = std::numbers::egamma * 42;
 
     sink(1 / Pi);
@@ -406,44 +406,44 @@ void baz(){
     sink(1 / bar::sqrt(Pi));
 
     sink(1 / bar::sqrt(MY_PI));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
 
 
     log(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::ln2;
 
     log(10);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::ln10;
 
     bar::sqrt(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt2;
 
     sink(1 / bar::sqrt(3));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' math constant [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
 
     bar::sqrt(3);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: std::numbers::sqrt3;
 
     T phi = 1.6180339;
-    // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
     // CHECK-FIXES: T phi = std::numbers::phi;
 
     sink((42 + bar::sqrt(5)) / 2);
 
     sink((1 + bar::sqrt(5)) / 2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::phi);
 
     sink((bar::sqrt(5.0F) + 1) / 2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' math constant [modernize-use-std-numbers]
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES: sink(std::numbers::phi_v<float>);
 }
 

>From b886daf14b3b7bf92345e40431bbdea072acf775 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 11 Nov 2023 00:13:43 +0100
Subject: [PATCH 29/44] add config value for DiffThreshold

---
 .../modernize/UseStdNumbersCheck.cpp          | 335 ++++++++-------
 .../clang-tidy/modernize/UseStdNumbersCheck.h |   3 +
 .../checkers/modernize/use-std-numbers.cpp    | 384 +++++++++---------
 3 files changed, 383 insertions(+), 339 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index cb7579d42a33c..6ac1fcc75c01c 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -42,9 +42,8 @@ using namespace clang::ast_matchers;
 using clang::ast_matchers::internal::Matcher;
 using llvm::StringRef;
 
-constexpr auto DiffThreshold = 0.001;
-
-AST_MATCHER_P(clang::FloatingLiteral, near, double, Value) {
+AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double,
+               DiffThreshold) {
   return std::abs(Node.getValueAsApproximateDouble() - Value) < DiffThreshold;
 }
 
@@ -75,176 +74,190 @@ AST_MATCHER_P(clang::Expr, anyOfExhaustive,
   return FoundMatch;
 }
 
-auto ignoreImplicitAndArithmeticCasting(const Matcher<clang::Expr> Matcher) {
-  return expr(
-      ignoringImplicit(expr(hasType(qualType(isArithmetic())),
-                            ignoringParenCasts(ignoringImplicit(Matcher)))));
-}
+// Using this struct to store the 'DiffThreshold' config value to create the
+// matchers without the need to pass 'DiffThreshold' into every matcher.
+// 'DiffThreshold' is needed in the 'near' matcher, which is used for matching
+// the literal of every constant and for formulas' subexpressions that look at
+// literals.
+struct MatchBuilder {
+  auto
+  ignoreImplicitAndArithmeticCasting(const Matcher<clang::Expr> Matcher) const {
+    return expr(
+        ignoringImplicit(expr(hasType(qualType(isArithmetic())),
+                              ignoringParenCasts(ignoringImplicit(Matcher)))));
+  }
 
-auto ignoreImplicitAndFloatingCasting(const Matcher<clang::Expr> Matcher) {
-  return expr(
-      ignoringImplicit(expr(hasType(qualType(isFloating())),
-                            ignoringParenCasts(ignoringImplicit(Matcher)))));
-}
+  auto
+  ignoreImplicitAndFloatingCasting(const Matcher<clang::Expr> Matcher) const {
+    return expr(
+        ignoringImplicit(expr(hasType(qualType(isFloating())),
+                              ignoringParenCasts(ignoringImplicit(Matcher)))));
+  }
 
-auto matchMathCall(const StringRef FunctionName,
-                   const Matcher<clang::Expr> ArgumentMatcher) {
-  return expr(ignoreImplicitAndFloatingCasting(
-      callExpr(callee(functionDecl(hasName(FunctionName),
-                                   hasParameter(0, hasType(isArithmetic())))),
-               hasArgument(0, ArgumentMatcher))));
-}
+  auto matchMathCall(const StringRef FunctionName,
+                     const Matcher<clang::Expr> ArgumentMatcher) const {
+    return expr(ignoreImplicitAndFloatingCasting(
+        callExpr(callee(functionDecl(hasName(FunctionName),
+                                     hasParameter(0, hasType(isArithmetic())))),
+                 hasArgument(0, ArgumentMatcher))));
+  }
 
-auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
-  return matchMathCall("sqrt", ArgumentMatcher);
-}
+  auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) const {
+    return matchMathCall("sqrt", ArgumentMatcher);
+  }
 
-// Used for top-level matchers (i.e. the match that replaces Val with its
-// constant).
-//
-// E.g. The matcher of `std::numbers::pi` uses this matcher to look to
-// floatLiterals that have the value of pi.
-//
-// If the match is for a top-level match, we only care about the literal.
-auto matchFloatLiteralNear(const StringRef Constant, const double Val) {
-  return expr(
-      ignoreImplicitAndFloatingCasting(floatLiteral(near(Val)).bind(Constant)));
-}
+  // Used for top-level matchers (i.e. the match that replaces Val with its
+  // constant).
+  //
+  // E.g. The matcher of `std::numbers::pi` uses this matcher to look to
+  // floatLiterals that have the value of pi.
+  //
+  // If the match is for a top-level match, we only care about the literal.
+  auto matchFloatLiteralNear(const StringRef Constant, const double Val) const {
+    return expr(ignoreImplicitAndFloatingCasting(
+        floatLiteral(near(Val, DiffThreshold)).bind(Constant)));
+  }
 
-// Used for non-top-level matchers (i.e. matchers that are used as inner
-// matchers for top-level matchers).
-//
-// E.g.: The matcher of `std::numbers::log2e` uses this matcher to check if `e`
-// of `log2(e)` is declared constant and initialized with the value for eulers
-// number.
-//
-// Here, we do care about literals and about DeclRefExprs to variable
-// declarations that are constant and initialized with `Val`. This allows
-// top-level matchers to see through declared constants for their inner matches
-// like the `std::numbers::log2e` matcher.
-auto matchFloatValueNear(const double Val) {
-  const auto Float = floatLiteral(near(Val));
-
-  const auto Dref = declRefExpr(
-      to(varDecl(hasType(qualType(isConstQualified(), isFloating())),
-                 hasInitializer(ignoreImplicitAndFloatingCasting(Float)))));
-  return expr(ignoreImplicitAndFloatingCasting(anyOf(Float, Dref)));
-}
+  // Used for non-top-level matchers (i.e. matchers that are used as inner
+  // matchers for top-level matchers).
+  //
+  // E.g.: The matcher of `std::numbers::log2e` uses this matcher to check if
+  // `e` of `log2(e)` is declared constant and initialized with the value for
+  // eulers number.
+  //
+  // Here, we do care about literals and about DeclRefExprs to variable
+  // declarations that are constant and initialized with `Val`. This allows
+  // top-level matchers to see through declared constants for their inner
+  // matches like the `std::numbers::log2e` matcher.
+  auto matchFloatValueNear(const double Val) const {
+    const auto Float = floatLiteral(near(Val, DiffThreshold));
+
+    const auto Dref = declRefExpr(
+        to(varDecl(hasType(qualType(isConstQualified(), isFloating())),
+                   hasInitializer(ignoreImplicitAndFloatingCasting(Float)))));
+    return expr(ignoreImplicitAndFloatingCasting(anyOf(Float, Dref)));
+  }
 
-auto matchValue(const int64_t ValInt) {
-  const auto Int =
-      expr(ignoreImplicitAndArithmeticCasting(integerLiteral(equals(ValInt))));
-  const auto Float = expr(ignoreImplicitAndFloatingCasting(
-      matchFloatValueNear(static_cast<double>(ValInt))));
-  const auto Dref = declRefExpr(to(varDecl(
-      hasType(qualType(isConstQualified(), isArithmetic())),
-      hasInitializer(expr(anyOf(ignoringImplicit(Int),
-                                ignoreImplicitAndFloatingCasting(Float)))))));
-  return expr(anyOf(Int, Float, Dref));
-}
+  auto matchValue(const int64_t ValInt) const {
+    const auto Int = expr(
+        ignoreImplicitAndArithmeticCasting(integerLiteral(equals(ValInt))));
+    const auto Float = expr(ignoreImplicitAndFloatingCasting(
+        matchFloatValueNear(static_cast<double>(ValInt))));
+    const auto Dref = declRefExpr(to(varDecl(
+        hasType(qualType(isConstQualified(), isArithmetic())),
+        hasInitializer(expr(anyOf(ignoringImplicit(Int),
+                                  ignoreImplicitAndFloatingCasting(Float)))))));
+    return expr(anyOf(Int, Float, Dref));
+  }
 
-auto match1Div(const Matcher<clang::Expr> Match) {
-  return binaryOperator(hasOperatorName("/"), hasLHS(matchValue(1)),
-                        hasRHS(ignoringImplicit(Match)));
-}
+  auto match1Div(const Matcher<clang::Expr> Match) const {
+    return binaryOperator(hasOperatorName("/"), hasLHS(matchValue(1)),
+                          hasRHS(ignoringImplicit(Match)));
+  }
 
-auto matchEuler() {
-  return expr(anyOf(matchFloatValueNear(llvm::numbers::e),
-                    matchMathCall("exp", matchValue(1))));
-}
-auto matchEulerTopLevel() {
-  return expr(anyOf(matchFloatLiteralNear("e_literal", llvm::numbers::e),
-                    matchMathCall("exp", matchValue(1)).bind("e_pattern")))
-      .bind("e");
-}
+  auto matchEuler() const {
+    return expr(anyOf(matchFloatValueNear(llvm::numbers::e),
+                      matchMathCall("exp", matchValue(1))));
+  }
+  auto matchEulerTopLevel() const {
+    return expr(anyOf(matchFloatLiteralNear("e_literal", llvm::numbers::e),
+                      matchMathCall("exp", matchValue(1)).bind("e_pattern")))
+        .bind("e");
+  }
 
-auto matchLog2Euler() {
-  return expr(
-             anyOf(matchFloatLiteralNear("log2e_literal", llvm::numbers::log2e),
+  auto matchLog2Euler() const {
+    return expr(
+               anyOf(
+                   matchFloatLiteralNear("log2e_literal", llvm::numbers::log2e),
                    matchMathCall("log2", matchEuler()).bind("log2e_pattern")))
-      .bind("log2e");
-}
+        .bind("log2e");
+  }
 
-auto matchLog10Euler() {
-  return expr(
-             anyOf(
-                 matchFloatLiteralNear("log10e_literal", llvm::numbers::log10e),
-                 matchMathCall("log10", matchEuler()).bind("log10e_pattern")))
-      .bind("log10e");
-}
+  auto matchLog10Euler() const {
+    return expr(
+               anyOf(
+                   matchFloatLiteralNear("log10e_literal",
+                                         llvm::numbers::log10e),
+                   matchMathCall("log10", matchEuler()).bind("log10e_pattern")))
+        .bind("log10e");
+  }
 
-auto matchPi() { return matchFloatValueNear(llvm::numbers::pi); }
-auto matchPiTopLevel() {
-  return matchFloatLiteralNear("pi_literal", llvm::numbers::pi).bind("pi");
-}
+  auto matchPi() const { return matchFloatValueNear(llvm::numbers::pi); }
+  auto matchPiTopLevel() const {
+    return matchFloatLiteralNear("pi_literal", llvm::numbers::pi).bind("pi");
+  }
 
-auto matchEgamma() {
-  return matchFloatLiteralNear("egamma_literal", llvm::numbers::egamma)
-      .bind("egamma");
-}
+  auto matchEgamma() const {
+    return matchFloatLiteralNear("egamma_literal", llvm::numbers::egamma)
+        .bind("egamma");
+  }
 
-auto matchInvPi() {
-  return expr(anyOf(matchFloatLiteralNear("inv_pi_literal",
-                                          llvm::numbers::inv_pi),
-                    match1Div(matchPi()).bind("inv_pi_pattern")))
-      .bind("inv_pi");
-}
+  auto matchInvPi() const {
+    return expr(anyOf(matchFloatLiteralNear("inv_pi_literal",
+                                            llvm::numbers::inv_pi),
+                      match1Div(matchPi()).bind("inv_pi_pattern")))
+        .bind("inv_pi");
+  }
 
-auto matchInvSqrtPi() {
-  return expr(anyOf(matchFloatLiteralNear("inv_sqrtpi_literal",
+  auto matchInvSqrtPi() const {
+    return expr(anyOf(
+                    matchFloatLiteralNear("inv_sqrtpi_literal",
                                           llvm::numbers::inv_sqrtpi),
                     match1Div(matchSqrt(matchPi())).bind("inv_sqrtpi_pattern")))
-      .bind("inv_sqrtpi");
-}
+        .bind("inv_sqrtpi");
+  }
 
-auto matchLn2() {
-  return expr(anyOf(matchFloatLiteralNear("ln2_literal", llvm::numbers::ln2),
-                    matchMathCall("log", ignoringImplicit(matchValue(2)))
-                        .bind("ln2_pattern")))
-      .bind("ln2");
-}
+  auto matchLn2() const {
+    return expr(anyOf(matchFloatLiteralNear("ln2_literal", llvm::numbers::ln2),
+                      matchMathCall("log", ignoringImplicit(matchValue(2)))
+                          .bind("ln2_pattern")))
+        .bind("ln2");
+  }
 
-auto machterLn10() {
-  return expr(anyOf(matchFloatLiteralNear("ln10_literal", llvm::numbers::ln10),
-                    matchMathCall("log", ignoringImplicit(matchValue(10)))
-                        .bind("ln10_pattern")))
-      .bind("ln10");
-}
+  auto machterLn10() const {
+    return expr(
+               anyOf(matchFloatLiteralNear("ln10_literal", llvm::numbers::ln10),
+                     matchMathCall("log", ignoringImplicit(matchValue(10)))
+                         .bind("ln10_pattern")))
+        .bind("ln10");
+  }
 
-auto matchSqrt2() {
-  return expr(
-             anyOf(matchFloatLiteralNear("sqrt2_literal", llvm::numbers::sqrt2),
-                   matchSqrt(matchValue(2)).bind("sqrt2_pattern")))
-      .bind("sqrt2");
-}
+  auto matchSqrt2() const {
+    return expr(anyOf(matchFloatLiteralNear("sqrt2_literal",
+                                            llvm::numbers::sqrt2),
+                      matchSqrt(matchValue(2)).bind("sqrt2_pattern")))
+        .bind("sqrt2");
+  }
 
-auto matchSqrt3() {
-  return expr(
-             anyOf(matchFloatLiteralNear("sqrt3_literal", llvm::numbers::sqrt3),
-                   matchSqrt(matchValue(3)).bind("sqrt3_pattern")))
-      .bind("sqrt3");
-}
+  auto matchSqrt3() const {
+    return expr(anyOf(matchFloatLiteralNear("sqrt3_literal",
+                                            llvm::numbers::sqrt3),
+                      matchSqrt(matchValue(3)).bind("sqrt3_pattern")))
+        .bind("sqrt3");
+  }
 
-auto matchInvSqrt3() {
-  return expr(
-             anyOf(
-                 matchFloatLiteralNear("inv_sqrt3_literal",
-                                       llvm::numbers::inv_sqrt3),
-                 match1Div(matchSqrt(matchValue(3))).bind("inv_sqrt3_pattern")))
-      .bind("inv_sqrt3");
-}
+  auto matchInvSqrt3() const {
+    return expr(anyOf(matchFloatLiteralNear("inv_sqrt3_literal",
+                                            llvm::numbers::inv_sqrt3),
+                      match1Div(matchSqrt(matchValue(3)))
+                          .bind("inv_sqrt3_pattern")))
+        .bind("inv_sqrt3");
+  }
 
-auto matchPhi() {
-  const auto PhiFormula = binaryOperator(
-      hasOperatorName("/"),
-      hasLHS(parenExpr(has(binaryOperator(
-          hasOperatorName("+"), hasEitherOperand(matchValue(1)),
-          hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
-      hasRHS(matchValue(2)));
-  return expr(anyOf(PhiFormula.bind("phi_pattern"),
-                    matchFloatLiteralNear("phi_literal", llvm::numbers::phi)))
-      .bind("phi");
-}
+  auto matchPhi() const {
+    const auto PhiFormula = binaryOperator(
+        hasOperatorName("/"),
+        hasLHS(parenExpr(has(binaryOperator(
+            hasOperatorName("+"), hasEitherOperand(matchValue(1)),
+            hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
+        hasRHS(matchValue(2)));
+    return expr(anyOf(PhiFormula.bind("phi_pattern"),
+                      matchFloatLiteralNear("phi_literal", llvm::numbers::phi)))
+        .bind("phi");
+  }
+
+  double DiffThreshold;
+};
 
 std::string getCode(const StringRef Constant, const bool IsFloat,
                     const bool IsLongDouble) {
@@ -286,14 +299,26 @@ UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name,
     : ClangTidyCheck(Name, Context),
       IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
                                                utils::IncludeSorter::IS_LLVM),
-                      areDiagsSelfContained()) {}
+                      areDiagsSelfContained()) {
+  DiffThresholdString = Options.get("DiffThreshold", "0.001");
+  if (DiffThresholdString.getAsDouble(DiffThreshold)) {
+    configurationDiag(
+        "Invalid DiffThreshold config value: '%0', expected a double")
+        << DiffThresholdString;
+    DiffThreshold = 0.001;
+  }
+}
 
 void UseStdNumbersCheck::registerMatchers(MatchFinder *Finder) {
+  const auto Matches = MatchBuilder{DiffThreshold};
   static const auto ConstantMatchers = {
-      matchLog2Euler(), matchLog10Euler(), matchEulerTopLevel(), matchEgamma(),
-      matchInvSqrtPi(), matchInvPi(),      matchPiTopLevel(),    matchLn2(),
-      machterLn10(),    matchSqrt2(),      matchInvSqrt3(),      matchSqrt3(),
-      matchPhi(),
+      Matches.matchLog2Euler(),     Matches.matchLog10Euler(),
+      Matches.matchEulerTopLevel(), Matches.matchEgamma(),
+      Matches.matchInvSqrtPi(),     Matches.matchInvPi(),
+      Matches.matchPiTopLevel(),    Matches.matchLn2(),
+      Matches.machterLn10(),        Matches.matchSqrt2(),
+      Matches.matchInvSqrt3(),      Matches.matchSqrt3(),
+      Matches.matchPhi(),
   };
 
   Finder->addMatcher(
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
index da52f2b9ab4ce..ef63987daea84 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
@@ -35,10 +35,13 @@ class UseStdNumbersCheck : public ClangTidyCheck {
                            Preprocessor *ModuleExpanderPP) override;
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override {
     Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+    Options.store(Opts, "DiffThreshold", DiffThresholdString);
   }
 
 private:
   utils::IncludeInserter IncludeInserter;
+  StringRef DiffThresholdString;
+  double DiffThreshold;
 };
 
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 71f01ffaeb8df..9b292e920e289 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -1,6 +1,7 @@
-// RUN: %check_clang_tidy -std=c++20 %s modernize-use-std-numbers %t
+// RUN: %check_clang_tidy -check-suffix=ALL -std=c++20 %s modernize-use-std-numbers %t
+// RUN: %check_clang_tidy -check-suffix=ALL,IMPRECISE -std=c++20 %s modernize-use-std-numbers %t -- -config="{CheckOptions: { modernize-use-std-numbers.DiffThreshold: 0.01 }}"
 
-// CHECK-FIXES: #include <numbers>
+// CHECK-FIXES-ALL: #include <numbers>
 
 namespace bar {
     double sqrt(double Arg);
@@ -9,8 +10,8 @@ namespace bar {
     auto sqrt(T val) { return sqrt(static_cast<double>(val)); }
 
     static constexpr double e = 2.718281828459045235360287471352662497757247093;
-    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e' to this literal, differs by '0.00e+00' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr double e = std::numbers::e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e' to this literal, differs by '0.00e+00' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr double e = std::numbers::e;
 }
 
 double exp(double Arg);
@@ -37,90 +38,100 @@ using my_float = float;
 
 void foo(){
     static constexpr double Pi = 3.1415926;
-    // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr double Pi = std::numbers::pi;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:34: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr double Pi = std::numbers::pi;
 
     static constexpr double Euler = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr double Euler = std::numbers::e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:37: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr double Euler = std::numbers::e;
 
     static constexpr double Phi = 1.6180339;
-    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr double Phi = std::numbers::phi;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:35: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr double Phi = std::numbers::phi;
 
     static constexpr double PiCopy = Pi;
     static constexpr double PiDefineFromMacro = MY_PI;
-    // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr double PiDefineFromMacro = std::numbers::pi;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:49: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr double PiDefineFromMacro = std::numbers::pi;
 
-    // not close enough to match value (DiffThreshold)
     static constexpr double Pi2 = 3.14;
+    // CHECK-MESSAGES-IMPRECISE: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi' to this literal, differs by '1.59e-03' [modernize-use-std-numbers]
+    // CHECK-FIXES-IMPRECISE: static constexpr double Pi2 = std::numbers::pi;
     static constexpr double Euler2 = 2.71;
+    // CHECK-MESSAGES-IMPRECISE: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '8.28e-03' [modernize-use-std-numbers]
+    // CHECK-FIXES-IMPRECISE: static constexpr double Euler2 = std::numbers::e;
     static constexpr double Phi2 = 1.61;
+    // CHECK-MESSAGES-IMPRECISE: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi' to this literal, differs by '8.03e-03' [modernize-use-std-numbers]
+    // CHECK-FIXES-IMPRECISE: static constexpr double Phi2 = std::numbers::phi;
 
     static constexpr double Pi3 = 3.1415926L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr double Pi3 = std::numbers::pi;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr double Pi3 = std::numbers::pi;
 
     static constexpr double Euler3 = 2.7182818L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr double Euler3 = std::numbers::e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr double Euler3 = std::numbers::e;
 
     static constexpr double Phi3 = 1.6180339L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr double Phi3 = std::numbers::phi;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr double Phi3 = std::numbers::phi;
 
     static constexpr long double Pi4 = 3.1415926L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr long double Pi4 = std::numbers::pi_v<long double>;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:40: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr long double Pi4 = std::numbers::pi_v<long double>;
 
     static constexpr long double Euler4 = 2.7182818L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer 'std::numbers::e_v<long double>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr long double Euler4 = std::numbers::e_v<long double>;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:43: warning: prefer 'std::numbers::e_v<long double>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr long double Euler4 = std::numbers::e_v<long double>;
 
     static constexpr long double Phi4 = 1.6180339L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::phi_v<long double>' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:41: warning: prefer 'std::numbers::phi_v<long double>' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
 
     static constexpr my_double Euler5 = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr my_double Euler5 = std::numbers::e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:41: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr my_double Euler5 = std::numbers::e;
 
     static constexpr my_float Euler6 = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::e_v<float>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr my_float Euler6 = std::numbers::e_v<float>;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:40: warning: prefer 'std::numbers::e_v<float>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr my_float Euler6 = std::numbers::e_v<float>;
 
     static constexpr int NotEuler7 = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr int NotEuler7 = std::numbers::e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr int NotEuler7 = std::numbers::e;
 
     static constexpr double InvPi = 1.0 / Pi;
-    // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::inv_pi'  to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr double InvPi = std::numbers::inv_pi;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:37: warning: prefer 'std::numbers::inv_pi'  to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr double InvPi = std::numbers::inv_pi;
 
     static constexpr my_float Actually2MyFloat = 2;
     bar::sqrt(Actually2MyFloat);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>'  to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::sqrt2_v<float>;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>'  to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::sqrt2_v<float>;
 
     sink(MY_PI);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: sink(std::numbers::pi);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: sink(std::numbers::pi);
+
+    auto X = 42.0;
+    auto Y = X * 3.14;
+    // CHECK-MESSAGES-IMPRECISE: :[[@LINE-1]]:18: warning: prefer 'std::numbers::pi' to this literal, differs by '1.59e-03' [modernize-use-std-numbers]
+    // CHECK-FIXES-IMPRECISE: auto Y = X * std::numbers::pi;
 
     constexpr static auto One = 1;
     constexpr static auto Two = 2;
 
     bar::sqrt(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::sqrt2;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::sqrt2;
 
     bar::sqrt(Two);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::sqrt2;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::sqrt2;
 
     bar::sqrt(2.0);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::sqrt2;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::sqrt2;
 
     auto Not2 = 2;
     Not2 = 42;
@@ -128,170 +139,170 @@ void foo(){
 
     const auto Actually2 = 2;
     bar::sqrt(Actually2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::sqrt2;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::sqrt2;
 
     exp(1);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::e;
 
     exp(One);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::e;
 
     exp(1.00000000000001);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::e;
 
     log2(exp(1));
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::log2e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES-ALL: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::log2e;
 
     log2(Euler);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::log2e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::log2e;
 
     log2(bar::e);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::log2e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::log2e;
 
     log2(Euler5);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::log2e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::log2e;
 
     log2(Euler6);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::log2e_v<float>;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::log2e_v<float>;
 
     log2(NotEuler7);
 
     auto log2e = 1.4426950;
-    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer 'std::numbers::log2e' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: auto log2e = std::numbers::log2e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:18: warning: prefer 'std::numbers::log2e' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: auto log2e = std::numbers::log2e;
 
     floatSink(log2(Euler));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<float>(log2(Euler)));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(1.4426950);
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<float>(1.4426950));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(log2(static_cast<float>(Euler)));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<float>(log2(static_cast<float>(Euler))));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<float>(log2(static_cast<int>(Euler))));
 
     floatSink(static_cast<int>(log2(static_cast<float>(Euler))));
-    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
 
     floatSink(1.4426950F);
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<double>(1.4426950F));
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<int>(1.4426950F));
-    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
 
     log10(exp(1));
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::log10e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES-ALL: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::log10e;
 
     log10(Euler);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::log10e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::log10e;
 
     log10(bar::e);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::log10e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::log10e;
 
     auto log10e = .434294;
-    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::log10e' to this literal, differs by '4.82e-07' [modernize-use-std-numbers]
-    // CHECK-FIXES: auto log10e = std::numbers::log10e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:19: warning: prefer 'std::numbers::log10e' to this literal, differs by '4.82e-07' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: auto log10e = std::numbers::log10e;
 
     auto egamma = 0.5772156 * 42;
-    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::egamma' to this literal, differs by '6.49e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: auto egamma = std::numbers::egamma * 42;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:19: warning: prefer 'std::numbers::egamma' to this literal, differs by '6.49e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: auto egamma = std::numbers::egamma * 42;
 
     sink(InvPi);
 
     sink(1 / Pi);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_pi' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: sink(std::numbers::inv_pi);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_pi' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: sink(std::numbers::inv_pi);
 
     sink(1 / bar::sqrt(Pi));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: sink(std::numbers::inv_sqrtpi);
 
     sink(1 / bar::sqrt(MY_PI));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES-ALL: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: sink(std::numbers::inv_sqrtpi);
 
     log(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::ln2;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::ln2;
 
     log(10);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::ln10;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::ln10;
 
     bar::sqrt(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::sqrt2;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::sqrt2;
 
     sink(1 / bar::sqrt(3));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this formula [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES-ALL: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: sink(std::numbers::inv_sqrt3);
 
     sink(INV_SQRT3);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this macro [modernize-use-std-numbers]
-    // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this macro [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: sink(std::numbers::inv_sqrt3);
 
     const auto inv_sqrt3f = .577350269F;
-    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::inv_sqrt3_v<float>' to this literal, differs by '1.04e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: const auto inv_sqrt3f = std::numbers::inv_sqrt3_v<float>;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:29: warning: prefer 'std::numbers::inv_sqrt3_v<float>' to this literal, differs by '1.04e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: const auto inv_sqrt3f = std::numbers::inv_sqrt3_v<float>;
 
     bar::sqrt(3);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::sqrt3;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::sqrt3;
 
     auto somePhi = 1.6180339;
-    // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: auto somePhi = std::numbers::phi;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:20: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: auto somePhi = std::numbers::phi;
 
     sink(Phi);
 
     sink((42 + bar::sqrt(5)) / 2);
 
     sink((1 + bar::sqrt(5)) / 2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: sink(std::numbers::phi);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: sink(std::numbers::phi);
 
     sink((bar::sqrt(5.0F) + 1) / 2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: sink(std::numbers::phi_v<float>);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: sink(std::numbers::phi_v<float>);
 }
 
 
@@ -299,56 +310,61 @@ void foo(){
 template <typename T>
 void baz(){
     static constexpr T Pi = 3.1415926;
-    // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr T Pi = std::numbers::pi;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:29: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr T Pi = std::numbers::pi;
 
     static constexpr T Euler = 2.7182818;
-    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr T Euler = std::numbers::e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:32: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr T Euler = std::numbers::e;
 
     static constexpr T Phi = 1.6180339;
-    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr T Phi = std::numbers::phi;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:30: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr T Phi = std::numbers::phi;
 
     static constexpr T PiCopy = Pi;
     static constexpr T PiDefineFromMacro = MY_PI;
-    // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr T PiDefineFromMacro = std::numbers::pi;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:44: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr T PiDefineFromMacro = std::numbers::pi;
 
-    // not close enough to match value (DiffThreshold)
     static constexpr T Pi2 = 3.14;
+    // CHECK-MESSAGES-IMPRECISE: :[[@LINE-1]]:30: warning: prefer 'std::numbers::pi' to this literal, differs by '1.59e-03' [modernize-use-std-numbers]
+    // CHECK-FIXES-IMPRECISE: static constexpr T Pi2 = std::numbers::pi;
     static constexpr T Euler2 = 2.71;
+    // CHECK-MESSAGES-IMPRECISE: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e' to this literal, differs by '8.28e-03' [modernize-use-std-numbers]
+    // CHECK-FIXES-IMPRECISE: static constexpr T Euler2 = std::numbers::e;
     static constexpr T Phi2 = 1.61;
+    // CHECK-MESSAGES-IMPRECISE: :[[@LINE-1]]:31: warning: prefer 'std::numbers::phi' to this literal, differs by '8.03e-03' [modernize-use-std-numbers]
+    // CHECK-FIXES-IMPRECISE: static constexpr T Phi2 = std::numbers::phi;
 
     static constexpr T Pi3 = 3.1415926L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr T Pi3 = std::numbers::pi_v<long double>;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:30: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr T Pi3 = std::numbers::pi_v<long double>;
 
     static constexpr T Euler3 = 2.7182818L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e_v<long double>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr T Euler3 = std::numbers::e_v<long double>;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e_v<long double>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr T Euler3 = std::numbers::e_v<long double>;
 
     static constexpr T Phi3 = 1.6180339L;
-    // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer 'std::numbers::phi_v<long double>' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: static constexpr T Phi3 = std::numbers::phi_v<long double>;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:31: warning: prefer 'std::numbers::phi_v<long double>' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr T Phi3 = std::numbers::phi_v<long double>;
 
     static constexpr my_float Actually2MyFloat = 2;
     bar::sqrt(Actually2MyFloat);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::sqrt2_v<float>;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::sqrt2_v<float>;
 
     constexpr static T One = 1;
     constexpr static T Two = 2;
 
     bar::sqrt(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::sqrt2;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::sqrt2;
 
     bar::sqrt(Two);
 
     bar::sqrt(2.0);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::sqrt2;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::sqrt2;
 
     T Not2 = 2;
     Not2 = 42;
@@ -358,93 +374,93 @@ void baz(){
     bar::sqrt(Actually2);
 
     exp(1);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::e;
 
     exp(One);
 
     exp(1.00000000000001);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::e;
 
     log2(exp(1));
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::log2e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES-ALL: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::log2e;
 
     log2(Euler);
 
     log2(bar::e);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::log2e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::log2e;
 
     T log2e = 1.4426950;
-    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: T log2e = std::numbers::log2e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: T log2e = std::numbers::log2e;
 
     log10(exp(1));
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::log10e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES-ALL: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::log10e;
 
     log10(Euler);
 
     log10(bar::e);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::log10e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::log10e;
 
     T log10e = .434294;
-    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::log10e' to this literal, differs by '4.82e-07' [modernize-use-std-numbers]
-    // CHECK-FIXES: T log10e = std::numbers::log10e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:16: warning: prefer 'std::numbers::log10e' to this literal, differs by '4.82e-07' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: T log10e = std::numbers::log10e;
 
     T egamma = 0.5772156 * 42;
-    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::egamma' to this literal, differs by '6.49e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: T egamma = std::numbers::egamma * 42;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:16: warning: prefer 'std::numbers::egamma' to this literal, differs by '6.49e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: T egamma = std::numbers::egamma * 42;
 
     sink(1 / Pi);
 
     sink(1 / bar::sqrt(Pi));
 
     sink(1 / bar::sqrt(MY_PI));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES-ALL: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: sink(std::numbers::inv_sqrtpi);
 
 
     log(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::ln2;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::ln2;
 
     log(10);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::ln10;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::ln10;
 
     bar::sqrt(2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::sqrt2;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::sqrt2;
 
     sink(1 / bar::sqrt(3));
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this formula [modernize-use-std-numbers]
-    // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this formula [modernize-use-std-numbers]
+    // CHECK-MESSAGES-ALL: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: sink(std::numbers::inv_sqrt3);
 
     bar::sqrt(3);
-    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: std::numbers::sqrt3;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: std::numbers::sqrt3;
 
     T phi = 1.6180339;
-    // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES: T phi = std::numbers::phi;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: T phi = std::numbers::phi;
 
     sink((42 + bar::sqrt(5)) / 2);
 
     sink((1 + bar::sqrt(5)) / 2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: sink(std::numbers::phi);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: sink(std::numbers::phi);
 
     sink((bar::sqrt(5.0F) + 1) / 2);
-    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES: sink(std::numbers::phi_v<float>);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: sink(std::numbers::phi_v<float>);
 }
 
 template <typename T>

>From d25045a67aff19718a01d8f438016946aa870bb8 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 11 Nov 2023 02:56:44 +0100
Subject: [PATCH 30/44] use TK_IgnoreUnlessSpelledInSource

- makes some matchers a little bit more readable
- removes the need for the double `ignoringImplicit`
  in the custom ignoringParenAnd_Casting
---
 .../modernize/UseStdNumbersCheck.cpp          | 48 +++++++++----------
 1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 6ac1fcc75c01c..0246a035b394b 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -9,6 +9,7 @@
 #include "UseStdNumbersCheck.h"
 #include "../ClangTidyDiagnosticConsumer.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTTypeTraits.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Stmt.h"
@@ -81,22 +82,18 @@ AST_MATCHER_P(clang::Expr, anyOfExhaustive,
 // literals.
 struct MatchBuilder {
   auto
-  ignoreImplicitAndArithmeticCasting(const Matcher<clang::Expr> Matcher) const {
-    return expr(
-        ignoringImplicit(expr(hasType(qualType(isArithmetic())),
-                              ignoringParenCasts(ignoringImplicit(Matcher)))));
+  ignoreParenAndArithmeticCasting(const Matcher<clang::Expr> Matcher) const {
+    return expr(hasType(qualType(isArithmetic())),
+                ignoringParenCasts((Matcher)));
   }
 
-  auto
-  ignoreImplicitAndFloatingCasting(const Matcher<clang::Expr> Matcher) const {
-    return expr(
-        ignoringImplicit(expr(hasType(qualType(isFloating())),
-                              ignoringParenCasts(ignoringImplicit(Matcher)))));
+  auto ignoreParenAndFloatingCasting(const Matcher<clang::Expr> Matcher) const {
+    return expr(hasType(qualType(isFloating())), ignoringParenCasts((Matcher)));
   }
 
   auto matchMathCall(const StringRef FunctionName,
                      const Matcher<clang::Expr> ArgumentMatcher) const {
-    return expr(ignoreImplicitAndFloatingCasting(
+    return expr(ignoreParenAndFloatingCasting(
         callExpr(callee(functionDecl(hasName(FunctionName),
                                      hasParameter(0, hasType(isArithmetic())))),
                  hasArgument(0, ArgumentMatcher))));
@@ -114,7 +111,7 @@ struct MatchBuilder {
   //
   // If the match is for a top-level match, we only care about the literal.
   auto matchFloatLiteralNear(const StringRef Constant, const double Val) const {
-    return expr(ignoreImplicitAndFloatingCasting(
+    return expr(ignoreParenAndFloatingCasting(
         floatLiteral(near(Val, DiffThreshold)).bind(Constant)));
   }
 
@@ -134,25 +131,25 @@ struct MatchBuilder {
 
     const auto Dref = declRefExpr(
         to(varDecl(hasType(qualType(isConstQualified(), isFloating())),
-                   hasInitializer(ignoreImplicitAndFloatingCasting(Float)))));
-    return expr(ignoreImplicitAndFloatingCasting(anyOf(Float, Dref)));
+                   hasInitializer(ignoreParenAndFloatingCasting(Float)))));
+    return expr(ignoreParenAndFloatingCasting(anyOf(Float, Dref)));
   }
 
   auto matchValue(const int64_t ValInt) const {
-    const auto Int = expr(
-        ignoreImplicitAndArithmeticCasting(integerLiteral(equals(ValInt))));
-    const auto Float = expr(ignoreImplicitAndFloatingCasting(
+    const auto Int =
+        expr(ignoreParenAndArithmeticCasting(integerLiteral(equals(ValInt))));
+    const auto Float = expr(ignoreParenAndFloatingCasting(
         matchFloatValueNear(static_cast<double>(ValInt))));
     const auto Dref = declRefExpr(to(varDecl(
         hasType(qualType(isConstQualified(), isArithmetic())),
         hasInitializer(expr(anyOf(ignoringImplicit(Int),
-                                  ignoreImplicitAndFloatingCasting(Float)))))));
+                                  ignoreParenAndFloatingCasting(Float)))))));
     return expr(anyOf(Int, Float, Dref));
   }
 
   auto match1Div(const Matcher<clang::Expr> Match) const {
     return binaryOperator(hasOperatorName("/"), hasLHS(matchValue(1)),
-                          hasRHS(ignoringImplicit(Match)));
+                          hasRHS(Match));
   }
 
   auto matchEuler() const {
@@ -209,16 +206,14 @@ struct MatchBuilder {
 
   auto matchLn2() const {
     return expr(anyOf(matchFloatLiteralNear("ln2_literal", llvm::numbers::ln2),
-                      matchMathCall("log", ignoringImplicit(matchValue(2)))
-                          .bind("ln2_pattern")))
+                      matchMathCall("log", matchValue(2)).bind("ln2_pattern")))
         .bind("ln2");
   }
 
   auto machterLn10() const {
     return expr(
                anyOf(matchFloatLiteralNear("ln10_literal", llvm::numbers::ln10),
-                     matchMathCall("log", ignoringImplicit(matchValue(10)))
-                         .bind("ln10_pattern")))
+                     matchMathCall("log", matchValue(10)).bind("ln10_pattern")))
         .bind("ln10");
   }
 
@@ -247,9 +242,9 @@ struct MatchBuilder {
   auto matchPhi() const {
     const auto PhiFormula = binaryOperator(
         hasOperatorName("/"),
-        hasLHS(parenExpr(has(binaryOperator(
+        hasLHS(binaryOperator(
             hasOperatorName("+"), hasEitherOperand(matchValue(1)),
-            hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
+            hasEitherOperand(matchMathCall("sqrt", matchValue(5))))),
         hasRHS(matchValue(2)));
     return expr(anyOf(PhiFormula.bind("phi_pattern"),
                       matchFloatLiteralNear("phi_literal", llvm::numbers::phi)))
@@ -321,8 +316,11 @@ void UseStdNumbersCheck::registerMatchers(MatchFinder *Finder) {
       Matches.matchPhi(),
   };
 
+  // Using 'TK_IgnoreUnlessSpelledInSource' here instead of at the check level
+  // to figure out what the type is that the matched constants are used as.
   Finder->addMatcher(
-      expr(anyOfExhaustive(ConstantMatchers),
+      expr(traverse(TK_IgnoreUnlessSpelledInSource,
+                    expr(anyOfExhaustive(ConstantMatchers))),
            unless(isInTemplateInstantiation()),
            unless(hasParent(expr(
                anyOf(implicitCastExpr(hasImplicitDestinationType(isFloating())),

>From 8343233c24d5fd0076002c0b025fe440515fab8c Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 16 Nov 2023 03:40:25 +0100
Subject: [PATCH 31/44] rm duplicate canonicalization of expr type

---
 .../clang-tidy/modernize/UseStdNumbersCheck.cpp           | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 0246a035b394b..c510ddfd5acf5 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -325,10 +325,10 @@ void UseStdNumbersCheck::registerMatchers(MatchFinder *Finder) {
            unless(hasParent(expr(
                anyOf(implicitCastExpr(hasImplicitDestinationType(isFloating())),
                      explicitCastExpr(hasDestinationType(isFloating())))))),
-           hasType(qualType(hasCanonicalType(hasCanonicalTypeUnqualified(anyOf(
-               qualType(asString("float")).bind("float"),
-               qualType(asString("double")),
-               qualType(asString("long double")).bind("long double"))))))),
+           hasType(qualType(hasCanonicalTypeUnqualified(
+               anyOf(qualType(asString("float")).bind("float"),
+                     qualType(asString("double")),
+                     qualType(asString("long double")).bind("long double")))))),
       this);
 }
 

>From b802286ce9e672cd4017be488f69d6bb28d91080 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 16 Nov 2023 03:50:32 +0100
Subject: [PATCH 32/44] rm not needed parens

---
 .../clang-tidy/modernize/UseStdNumbersCheck.cpp              | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index c510ddfd5acf5..6c46d504d346e 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -83,12 +83,11 @@ AST_MATCHER_P(clang::Expr, anyOfExhaustive,
 struct MatchBuilder {
   auto
   ignoreParenAndArithmeticCasting(const Matcher<clang::Expr> Matcher) const {
-    return expr(hasType(qualType(isArithmetic())),
-                ignoringParenCasts((Matcher)));
+    return expr(hasType(qualType(isArithmetic())), ignoringParenCasts(Matcher));
   }
 
   auto ignoreParenAndFloatingCasting(const Matcher<clang::Expr> Matcher) const {
-    return expr(hasType(qualType(isFloating())), ignoringParenCasts((Matcher)));
+    return expr(hasType(qualType(isFloating())), ignoringParenCasts(Matcher));
   }
 
   auto matchMathCall(const StringRef FunctionName,

>From 30ff6eecd23756e9465187c7546ba1bc833dd213 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 16 Nov 2023 03:51:45 +0100
Subject: [PATCH 33/44] declare PatternBindString in the if-init

---
 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 6c46d504d346e..0dfcfa8d23d52 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -391,8 +391,8 @@ void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
       continue;
     }
 
-    const auto PatternBindString = (ConstantName + "_pattern").str();
-    if (Result.Nodes.getNodeAs<Expr>(PatternBindString) != nullptr) {
+    if (const auto PatternBindString = (ConstantName + "_pattern").str();
+        Result.Nodes.getNodeAs<Expr>(PatternBindString) != nullptr) {
       const auto Code = getCode(ConstantName, IsFloat, IsLongDouble);
       diag(Range.getBegin(), "prefer '%0' to this %select{formula|macro}1")
           << Code << IsMacro << FixItHint::CreateReplacement(Range, Code);

>From b5803cdde1efccb44201519f58335d3d94ef2103 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 16 Nov 2023 03:53:45 +0100
Subject: [PATCH 34/44] more const parameters

---
 .../clang-tidy/modernize/UseStdNumbersCheck.cpp           | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 0dfcfa8d23d52..513d6468399d3 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -303,7 +303,7 @@ UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name,
   }
 }
 
-void UseStdNumbersCheck::registerMatchers(MatchFinder *Finder) {
+void UseStdNumbersCheck::registerMatchers(MatchFinder *const Finder) {
   const auto Matches = MatchBuilder{DiffThreshold};
   static const auto ConstantMatchers = {
       Matches.matchLog2Euler(),     Matches.matchLog10Euler(),
@@ -436,9 +436,9 @@ void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
              Result.SourceManager->getFileID(Range.getBegin()), "<numbers>");
 }
 
-void UseStdNumbersCheck::registerPPCallbacks(const SourceManager &SM,
-                                             Preprocessor *PP,
-                                             Preprocessor *ModuleExpanderPP) {
+void UseStdNumbersCheck::registerPPCallbacks(
+    const SourceManager &SM, Preprocessor *const PP,
+    Preprocessor *const ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
 }
 } // namespace clang::tidy::modernize

>From ce0a7846b1e8d5bf67b3a60246e76218995b2390 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 16 Nov 2023 03:54:49 +0100
Subject: [PATCH 35/44] init DiffThresholdString in the init list

---
 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 513d6468399d3..ed8cc6c6b255d 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -293,8 +293,8 @@ UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name,
     : ClangTidyCheck(Name, Context),
       IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
                                                utils::IncludeSorter::IS_LLVM),
-                      areDiagsSelfContained()) {
-  DiffThresholdString = Options.get("DiffThreshold", "0.001");
+                      areDiagsSelfContained()),
+      DiffThresholdString{Options.get("DiffThreshold", "0.001")} {
   if (DiffThresholdString.getAsDouble(DiffThreshold)) {
     configurationDiag(
         "Invalid DiffThreshold config value: '%0', expected a double")

>From a3f55401e7acfad14027c117b463d86e2496fab4 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 16 Nov 2023 04:12:23 +0100
Subject: [PATCH 36/44] add comment for isRangeOfCompleteMacro

---
 .../clang-tidy/modernize/UseStdNumbersCheck.cpp           | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index ed8cc6c6b255d..e25c15d82eaf0 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -387,6 +387,9 @@ void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
     const auto Range = Match->getSourceRange();
 
     const auto IsMacro = Range.getBegin().isMacroID();
+
+    // We do not want to emit a diagnostic when we are matching a macro, but the
+    // match inside of the macro does not cover the whole macro.
     if (IsMacro && !isRangeOfCompleteMacro(Range, SM, LO)) {
       continue;
     }
@@ -410,7 +413,7 @@ void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
   }
 
   // We may have had no matches with literals, but a match with a pattern that
-  // was a subexpression of a macro which was therefore skipped.
+  // was a part of a macro which was therefore skipped.
   if (MatchedLiterals.empty()) {
     return;
   }
@@ -423,6 +426,9 @@ void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
 
   const auto Range = Node->getSourceRange();
   const auto IsMacro = Range.getBegin().isMacroID();
+
+  // We do not want to emit a diagnostic when we are matching a macro, but the
+  // match inside of the macro does not cover the whole macro.
   if (IsMacro && !isRangeOfCompleteMacro(Range, SM, LO)) {
     return;
   }

>From d89b10ab0fc3beec554f6a687e18aadc75447825 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 16 Nov 2023 04:13:37 +0100
Subject: [PATCH 37/44] add explicit tests for macro range check

---
 .../checkers/modernize/use-std-numbers.cpp       | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 9b292e920e289..c0962fb8e6990 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -32,6 +32,7 @@ void floatSink(float) {}
 #define MY_PI 3.1415926
 
 #define INV_SQRT3 1 / bar::sqrt(3)
+#define NOT_INV_SQRT3 1 / bar::sqrt(3) + 1
 
 using my_double = double;
 using my_float = float;
@@ -280,6 +281,8 @@ void foo(){
     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this macro [modernize-use-std-numbers]
     // CHECK-FIXES-ALL: sink(std::numbers::inv_sqrt3);
 
+    sink(NOT_INV_SQRT3);
+
     const auto inv_sqrt3f = .577350269F;
     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:29: warning: prefer 'std::numbers::inv_sqrt3_v<float>' to this literal, differs by '1.04e-08' [modernize-use-std-numbers]
     // CHECK-FIXES-ALL: const auto inv_sqrt3f = std::numbers::inv_sqrt3_v<float>;
@@ -471,3 +474,16 @@ void foobar(){
 void use_foobar() {
     foobar<float>();
 }
+
+#define BIG_MARCO                                                              \
+  struct InvSqrt3 {                                                            \
+    template <typename T> static T get() { return 1 / bar::sqrt(3); }          \
+  }
+
+BIG_MARCO;
+
+void use_BIG_MACRO() {
+InvSqrt3 f{};
+f.get<float>();
+f.get<double>();
+}

>From 31f7ac29c63662f75543a53dd5454b2796dc2b42 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 17 Nov 2023 23:47:13 +0100
Subject: [PATCH 38/44] instantiate big test template

---
 .../test/clang-tidy/checkers/modernize/use-std-numbers.cpp  | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index c0962fb8e6990..79ad0ecf5b75a 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -471,8 +471,12 @@ void foobar(){
     const T Two = 2;
     bar::sqrt(Two);
 }
-void use_foobar() {
+void use_templates() {
     foobar<float>();
+    foobar<double>();
+
+    baz<float>();
+    baz<double>();
 }
 
 #define BIG_MARCO                                                              \

>From 030eabfda92bee3ae7e9ea1410f97d6705436d5e Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 23 Nov 2023 20:09:29 +0100
Subject: [PATCH 39/44] fix comment

---
 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index e25c15d82eaf0..17a1d85148f81 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -105,7 +105,7 @@ struct MatchBuilder {
   // Used for top-level matchers (i.e. the match that replaces Val with its
   // constant).
   //
-  // E.g. The matcher of `std::numbers::pi` uses this matcher to look to
+  // E.g. The matcher of `std::numbers::pi` uses this matcher to look for
   // floatLiterals that have the value of pi.
   //
   // If the match is for a top-level match, we only care about the literal.

>From bb0b1b33a9fffb5527a502401cf20cb2eba73ee3 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 23 Nov 2023 20:09:37 +0100
Subject: [PATCH 40/44] rm unless(isInTemplateInstantiation()), because of
 IgnoreUnlessSpelledInSource

---
 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 17a1d85148f81..88317948f053d 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -320,7 +320,6 @@ void UseStdNumbersCheck::registerMatchers(MatchFinder *const Finder) {
   Finder->addMatcher(
       expr(traverse(TK_IgnoreUnlessSpelledInSource,
                     expr(anyOfExhaustive(ConstantMatchers))),
-           unless(isInTemplateInstantiation()),
            unless(hasParent(expr(
                anyOf(implicitCastExpr(hasImplicitDestinationType(isFloating())),
                      explicitCastExpr(hasDestinationType(isFloating())))))),

>From 27d2eec25f4b6d98bf4b69bef56ab9fb2a6fd083 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 2 Dec 2023 14:57:39 +0100
Subject: [PATCH 41/44] fix literal in template problem in exchange for not
 resolving implicit casts

---
 .../modernize/UseStdNumbersCheck.cpp          | 18 +++++-------
 .../clang-tidy/modernize/UseStdNumbersCheck.h |  3 ++
 .../checks/modernize/use-std-numbers.rst      | 26 ++++++++---------
 .../checkers/modernize/use-std-numbers.cpp    | 28 +++++++++----------
 4 files changed, 37 insertions(+), 38 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 88317948f053d..450a289eb8f95 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -315,18 +315,14 @@ void UseStdNumbersCheck::registerMatchers(MatchFinder *const Finder) {
       Matches.matchPhi(),
   };
 
-  // Using 'TK_IgnoreUnlessSpelledInSource' here instead of at the check level
-  // to figure out what the type is that the matched constants are used as.
   Finder->addMatcher(
-      expr(traverse(TK_IgnoreUnlessSpelledInSource,
-                    expr(anyOfExhaustive(ConstantMatchers))),
-           unless(hasParent(expr(
-               anyOf(implicitCastExpr(hasImplicitDestinationType(isFloating())),
-                     explicitCastExpr(hasDestinationType(isFloating())))))),
-           hasType(qualType(hasCanonicalTypeUnqualified(
-               anyOf(qualType(asString("float")).bind("float"),
-                     qualType(asString("double")),
-                     qualType(asString("long double")).bind("long double")))))),
+      expr(
+          anyOfExhaustive(ConstantMatchers),
+          unless(hasParent(explicitCastExpr(hasDestinationType(isFloating())))),
+          hasType(qualType(hasCanonicalTypeUnqualified(
+              anyOf(qualType(asString("float")).bind("float"),
+                    qualType(asString("double")),
+                    qualType(asString("long double")).bind("long double")))))),
       this);
 }
 
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
index ef63987daea84..cab3fe548c49c 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
@@ -37,6 +37,9 @@ class UseStdNumbersCheck : public ClangTidyCheck {
     Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
     Options.store(Opts, "DiffThreshold", DiffThresholdString);
   }
+  std::optional<TraversalKind> getCheckTraversalKind() const override {
+    return TK_IgnoreUnlessSpelledInSource;
+  }
 
 private:
   utils::IncludeInserter IncludeInserter;
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
index e51da6575958b..6a6038cb8fab5 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -31,28 +31,28 @@ The following list of constants from the ``numbers`` header are supported:
 
 The list currently includes all constants as of C++20.
 
-The replacements try to match the type of the inserted constant by how the
-removed expression was used, e.g., switching between ``std::numbers::e`` to
-``std::numbers::e_v<float>`` or ``std::numbers::e_v<long double>``
+The replacements use the type of the matched constant and can remove explicit casts,
+i.e., switching between ``std::numbers::e``, ``std::numbers::e_v<float>`` and ``std::numbers::e_v<long double>``
 where appropriate.
 
 .. code-block:: c++
 
     double sqrt(double);
-    double log(double);
+    double log2(double);
     void sink(auto&&) {}
     void floatSink(float);
 
     #define MY_PI 3.1415926
 
     void foo() {
-        const double Pi = 3.141592653589;  // const double Pi = std::numbers::pi
-        const auto Use = Pi / 2;           // no match for Pi
-        static constexpr double Euler = 2.7182818; // static constexpr double Euler = std::numbers::e;
-
-        log2(exp(1));     // std::numbers::log2e;
-        log2(Euler);      // std::numbers::log2e;
-        1 / sqrt(MY_PI);  // std::numbers::inv_sqrtpi;
-        sink(MY_PI);      // sink(std::numbers::pi);
-        floatSink(MY_PI); // floatSink(std::numbers::pi_v<float>);
+        const double Pi = 3.141592653589;           // const double Pi = std::numbers::pi
+        const auto Use = Pi / 2;                    // no match for Pi
+        static constexpr double Euler = 2.7182818;  // static constexpr double Euler = std::numbers::e;
+
+        log2(exp(1));                               // std::numbers::log2e;
+        log2(Euler);                                // std::numbers::log2e;
+        1 / sqrt(MY_PI);                            // std::numbers::inv_sqrtpi;
+        sink(MY_PI);                                // sink(std::numbers::pi);
+        floatSink(MY_PI);                           // floatSink(std::numbers::pi);
+        floatSink(static_cast<float>(MY_PI));       // floatSink(std::numbers::pi_v<float>);
     }
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 79ad0ecf5b75a..6c5762da5e2e8 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -66,16 +66,16 @@ void foo(){
     // CHECK-FIXES-IMPRECISE: static constexpr double Phi2 = std::numbers::phi;
 
     static constexpr double Pi3 = 3.1415926L;
-    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES-ALL: static constexpr double Pi3 = std::numbers::pi;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr double Pi3 = std::numbers::pi_v<long double>;
 
     static constexpr double Euler3 = 2.7182818L;
-    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES-ALL: static constexpr double Euler3 = std::numbers::e;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e_v<long double>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr double Euler3 = std::numbers::e_v<long double>;
 
     static constexpr double Phi3 = 1.6180339L;
-    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES-ALL: static constexpr double Phi3 = std::numbers::phi;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi_v<long double>' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr double Phi3 = std::numbers::phi_v<long double>;
 
     static constexpr long double Pi4 = 3.1415926L;
     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:40: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
@@ -94,8 +94,8 @@ void foo(){
     // CHECK-FIXES-ALL: static constexpr my_double Euler5 = std::numbers::e;
 
     static constexpr my_float Euler6 = 2.7182818;
-    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:40: warning: prefer 'std::numbers::e_v<float>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES-ALL: static constexpr my_float Euler6 = std::numbers::e_v<float>;
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:40: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: static constexpr my_float Euler6 = std::numbers::e;
 
     static constexpr int NotEuler7 = 2.7182818;
     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
@@ -183,16 +183,16 @@ void foo(){
     // CHECK-FIXES-ALL: auto log2e = std::numbers::log2e;
 
     floatSink(log2(Euler));
-    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
-    // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: floatSink(std::numbers::log2e);
 
     floatSink(static_cast<float>(log2(Euler)));
     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
     // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(1.4426950);
-    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: floatSink(std::numbers::log2e);
 
     floatSink(static_cast<float>(1.4426950));
     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
@@ -217,8 +217,8 @@ void foo(){
     // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
 
     floatSink(static_cast<double>(1.4426950F));
-    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
-    // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
+    // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
+    // CHECK-FIXES-ALL: floatSink(std::numbers::log2e);
 
     floatSink(static_cast<int>(1.4426950F));
     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]

>From e27646aa6e84de078d023f30ba5bc281a4ea3510 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 2 Dec 2023 15:10:18 +0100
Subject: [PATCH 42/44] move def of storeOptions to cpp file

---
 .../clang-tidy/modernize/UseStdNumbersCheck.cpp              | 5 +++++
 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h  | 5 +----
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 450a289eb8f95..7a29c0f1cca8d 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -442,4 +442,9 @@ void UseStdNumbersCheck::registerPPCallbacks(
     Preprocessor *const ModuleExpanderPP) {
   IncludeInserter.registerPreprocessor(PP);
 }
+
+void UseStdNumbersCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+  Options.store(Opts, "DiffThreshold", DiffThresholdString);
+}
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
index cab3fe548c49c..05fc5ada14b87 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
@@ -33,10 +33,7 @@ class UseStdNumbersCheck : public ClangTidyCheck {
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
   void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
                            Preprocessor *ModuleExpanderPP) override;
-  void storeOptions(ClangTidyOptions::OptionMap &Opts) override {
-    Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
-    Options.store(Opts, "DiffThreshold", DiffThresholdString);
-  }
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   std::optional<TraversalKind> getCheckTraversalKind() const override {
     return TK_IgnoreUnlessSpelledInSource;
   }

>From ec1a340adbac7dbfaca4191bd5cdbf2b0e1b4968 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 2 Dec 2023 15:11:13 +0100
Subject: [PATCH 43/44] remove unused include

---
 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 7a29c0f1cca8d..1f2b034713ecf 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -9,7 +9,6 @@
 #include "UseStdNumbersCheck.h"
 #include "../ClangTidyDiagnosticConsumer.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTTypeTraits.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Stmt.h"

>From 60f4d26b33a0cf2526fc726030cc37a082f04990 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Mon, 4 Dec 2023 21:35:35 +0100
Subject: [PATCH 44/44] add options to doc

---
 .../checks/modernize/use-std-numbers.rst         | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
index 6a6038cb8fab5..9eed00bb93915 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -56,3 +56,19 @@ where appropriate.
         floatSink(MY_PI);                           // floatSink(std::numbers::pi);
         floatSink(static_cast<float>(MY_PI));       // floatSink(std::numbers::pi_v<float>);
     }
+
+Options
+-------
+
+.. option:: DiffThreshold
+
+    A floating point value that sets the detection threshold for when literals
+    match a constant.
+    A literal matches a constant if
+    ``abs(literal - constant) < DiffThreshold`` evaluates to true.
+    Default is `0.001`.
+
+.. option:: IncludeStyle
+
+   A string specifying which include-style is used, `llvm` or `google`. Default
+   is `llvm`.



More information about the cfe-commits mailing list