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

Julian Schmidt via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 27 16:46:20 PDT 2023


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

>From 8f5e9e6024b0db8f251625669adbc5d607da83cb 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/19] [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           |   3 +-
 .../checks/modernize/use-std-numbers.rst      |  25 ++
 .../checkers/modernize/use-std-numbers.cpp    | 205 ++++++++++
 8 files changed, 656 insertions(+), 1 deletion(-)
 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 717c400c4790330..d82353d74fbd0d4 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 73751cf2705068d..73584e20166f66a 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 000000000000000..c23dc6671013bc3
--- /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 000000000000000..5598d533a3ea716
--- /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 6d6f51998a01e57..02efc22a7fe164e 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -163,6 +163,12 @@ New checks
   Flags coroutines that suspend while a lock guard is in scope at the
   suspension point.
 
+- 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:`modernize-use-constraints
   <clang-tidy/checks/modernize/use-constraints>` check.
 
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 1baabceea06ef48..ae1d541e40387a1 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -82,7 +82,7 @@ Clang-Tidy Checks
    :doc:`bugprone-bad-signal-to-kill-thread <bugprone/bad-signal-to-kill-thread>`,
    :doc:`bugprone-bool-pointer-implicit-conversion <bugprone/bool-pointer-implicit-conversion>`, "Yes"
    :doc:`bugprone-branch-clone <bugprone/branch-clone>`,
-   :doc:`bugprone-compare-pointer-to-member-virtual-function <bugprone/compare-pointer-to-member-virtual-function>`, "Yes"
+   :doc:`bugprone-compare-pointer-to-member-virtual-function <bugprone/compare-pointer-to-member-virtual-function>`,
    :doc:`bugprone-copy-constructor-init <bugprone/copy-constructor-init>`, "Yes"
    :doc:`bugprone-dangling-handle <bugprone/dangling-handle>`,
    :doc:`bugprone-dynamic-static-initializers <bugprone/dynamic-static-initializers>`,
@@ -290,6 +290,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 000000000000000..7911f2f7f857b95
--- /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 000000000000000..2ba0525f38306df
--- /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 c52e8a625e5b098054ce24a5b9aa309ce4a290e8 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 16 Sep 2023 21:13:56 +0200
Subject: [PATCH 02/19] add "Yes" back to list.rst that mysteriously
 disappeared for unrelated check

---
 clang-tools-extra/docs/clang-tidy/checks/list.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index ae1d541e40387a1..dd90cd8ae92b424 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -82,7 +82,7 @@ Clang-Tidy Checks
    :doc:`bugprone-bad-signal-to-kill-thread <bugprone/bad-signal-to-kill-thread>`,
    :doc:`bugprone-bool-pointer-implicit-conversion <bugprone/bool-pointer-implicit-conversion>`, "Yes"
    :doc:`bugprone-branch-clone <bugprone/branch-clone>`,
-   :doc:`bugprone-compare-pointer-to-member-virtual-function <bugprone/compare-pointer-to-member-virtual-function>`,
+   :doc:`bugprone-compare-pointer-to-member-virtual-function <bugprone/compare-pointer-to-member-virtual-function>`, "Yes"
    :doc:`bugprone-copy-constructor-init <bugprone/copy-constructor-init>`, "Yes"
    :doc:`bugprone-dangling-handle <bugprone/dangling-handle>`,
    :doc:`bugprone-dynamic-static-initializers <bugprone/dynamic-static-initializers>`,

>From 3fd29e448efb12d4d06a930bfcc045990b8ad02f 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 03/19] fix lexicographical ordering in some places after
 rename

---
 clang-tools-extra/clang-tidy/modernize/CMakeLists.txt  |  2 +-
 .../clang-tidy/modernize/ModernizeTidyModule.cpp       |  2 +-
 clang-tools-extra/docs/ReleaseNotes.rst                | 10 +++++-----
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index d82353d74fbd0d4..b254d340c4e854a 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 73584e20166f66a..4f33db5b741a7ef 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"
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 02efc22a7fe164e..9fabdda3619ed82 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -163,17 +163,17 @@ New checks
   Flags coroutines that suspend while a lock guard is in scope at the
   suspension point.
 
+- New :doc:`modernize-use-constraints
+  <clang-tidy/checks/modernize/use-constraints>` check.
+
+  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:`modernize-use-constraints
-  <clang-tidy/checks/modernize/use-constraints>` check.
-
-  Replace ``enable_if`` with C++20 requires clauses.
-
 - New :doc:`performance-enum-size
   <clang-tidy/checks/performance/enum-size>` check.
 

>From 5603bead129dc3cd784574acc9a6c0832fa8e719 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 04/19] 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 c23dc6671013bc3..f4bcfb903ad080b 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 9fabdda3619ed82..bb75ecaf188f76a 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -172,7 +172,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 7911f2f7f857b95..ec443123334f559 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 4583f5fe62873cac03e299f80d2db9943f56fd30 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 05/19] 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 5598d533a3ea716..9fc98a1892b2935 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 ec443123334f559..613db21435177cc 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 308099afa1b602b23df7f3287e4e0ca9561824ca 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 06/19] 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 f4bcfb903ad080b..bce0ab2117a48e0 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 2ba0525f38306df..bc9ecdaf8bc924d 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 4cb2c2702116f533e4332a0d7711f9b83ae68ae4 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 07/19] 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 bce0ab2117a48e0..7fa4d00d4552044 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 d4815d8fbda40d628cbb6d725239fbb2f267419e 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 08/19] 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 7fa4d00d4552044..db92a1f50b7bc25 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 bc9ecdaf8bc924d..8914ffc1e05f426 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 a7e040d72af575597b7f0f5b1b2e311fc1da5720 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 09/19] 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 db92a1f50b7bc25..8b3fa976b74d451 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 09e9cf59cd2b5987b0ff1a3beb5813db709db03e 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 10/19] 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 8b3fa976b74d451..6fe31c43115ab5f 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 7e9e7333571b0fb9e01108182a11c9818ebc31d3 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 11/19] 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 6fe31c43115ab5f..799b5cc2aaa818e 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 f879acd2a0d7108602e4c1a24ffeb94291490972 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 12/19] 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 799b5cc2aaa818e..9e8863c91d0ffe6 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 62f63bb6b3866f3b8b17c067ce431eecf96cab96 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 13/19] 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 9e8863c91d0ffe6..2939a0f1d9ca717 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 8914ffc1e05f426..19efa3291ea3649 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 d0082775a763ef4a98ff67b3eac0b33839a458a3 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 14/19] 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 2939a0f1d9ca717..acbdcde06b32953 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 9fc98a1892b2935..3cf2d9244cc814a 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 613db21435177cc..5da01bd34eaf603 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 19efa3291ea3649..8fce42b901b1ac3 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 f3123f52d3b60fcb0929a99a90550ad4ce913181 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 15/19] 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 acbdcde06b32953..98beab00a01814f 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 abef64dd25f108df526ca849454faf19c6bb86f3 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 16/19] 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 8fce42b901b1ac3..2ceec289ce7c138 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 054b3b2a693a785fb6ff9bbd23582a2f18907cfc 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 17/19] 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 5da01bd34eaf603..8cd31498792828c 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 4b6acb07d7e3d818dac1615dda2ee290f7b2d58a 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 18/19] 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 98beab00a01814f..257ede0897d71d6 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 408b5825db9ebb0e0369d8916ab1ab7e8f9cab06 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 19/19] 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 257ede0897d71d6..5483e01a43dcb65 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;



More information about the cfe-commits mailing list