[clang-tools-extra] [clang-tidy] add modernize-use-std-numbers (PR #66583)
Julian Schmidt via cfe-commits
cfe-commits at lists.llvm.org
Mon Dec 4 12:39:05 PST 2023
https://github.com/5chmidti updated https://github.com/llvm/llvm-project/pull/66583
>From 561997a2947354f7112b1dce0b44c8d02bd58da5 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 16 Sep 2023 16:24:13 +0200
Subject: [PATCH 01/44] [clang-tidy] add modernize-use-std-numbers check
This check finds constants and function calls to math functions that can be replaced
with c++20's mathematical constants ('numbers' header) and offers fixit-hints.
Does not match the use of variables or macros with that value and instead, offers a replacement
at the definition of said variables and macros.
---
.../clang-tidy/modernize/CMakeLists.txt | 1 +
.../modernize/ModernizeTidyModule.cpp | 3 +
.../modernize/UseStdNumbersCheck.cpp | 377 ++++++++++++++++++
.../clang-tidy/modernize/UseStdNumbersCheck.h | 37 ++
clang-tools-extra/docs/ReleaseNotes.rst | 6 +
.../docs/clang-tidy/checks/list.rst | 1 +
.../checks/modernize/use-std-numbers.rst | 25 ++
.../checkers/modernize/use-std-numbers.cpp | 205 ++++++++++
8 files changed, 655 insertions(+)
create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index 717c400c47903..d82353d74fbd0 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -16,6 +16,7 @@ add_clang_library(clangTidyModernizeModule
MakeSharedCheck.cpp
MakeSmartPtrCheck.cpp
MakeUniqueCheck.cpp
+ UseStdNumbersCheck.cpp
ModernizeTidyModule.cpp
PassByValueCheck.cpp
RawStringLiteralCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 73751cf270506..73584e20166f6 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -18,6 +18,7 @@
#include "MacroToEnumCheck.h"
#include "MakeSharedCheck.h"
#include "MakeUniqueCheck.h"
+#include "UseStdNumbersCheck.h"
#include "PassByValueCheck.h"
#include "RawStringLiteralCheck.h"
#include "RedundantVoidArgCheck.h"
@@ -65,6 +66,8 @@ class ModernizeModule : public ClangTidyModule {
CheckFactories.registerCheck<MacroToEnumCheck>("modernize-macro-to-enum");
CheckFactories.registerCheck<MakeSharedCheck>("modernize-make-shared");
CheckFactories.registerCheck<MakeUniqueCheck>("modernize-make-unique");
+ CheckFactories.registerCheck<UseStdNumbersCheck>(
+ "modernize-use-std-numbers");
CheckFactories.registerCheck<PassByValueCheck>("modernize-pass-by-value");
CheckFactories.registerCheck<UseStdPrintCheck>("modernize-use-std-print");
CheckFactories.registerCheck<RawStringLiteralCheck>(
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
new file mode 100644
index 0000000000000..c23dc6671013b
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -0,0 +1,377 @@
+//===--- UseStdNumbersCheck.cpp - clang_tidy -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX_License_Identifier: Apache_2.0 WITH LLVM_exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "UseStdNumbersCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchersInternal.h"
+#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/TokenKinds.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/Token.h"
+#include "clang/Tooling/Transformer/RewriteRule.h"
+#include "clang/Tooling/Transformer/Stencil.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/MathExtras.h"
+#include <cstdint>
+#include <string>
+
+namespace {
+using namespace clang::ast_matchers;
+using clang::ast_matchers::internal::Matcher;
+using clang::transformer::addInclude;
+using clang::transformer::applyFirst;
+using clang::transformer::ASTEdit;
+using clang::transformer::cat;
+using clang::transformer::changeTo;
+using clang::transformer::edit;
+using clang::transformer::EditGenerator;
+using clang::transformer::flattenVector;
+using clang::transformer::RewriteRuleWith;
+using llvm::StringRef;
+
+constexpr double Pi = 3.141592653589793238462643383279502884197169399;
+constexpr double Euler = 2.718281828459045235360287471352662497757247093;
+constexpr double Phi = 1.618033988749894848204586834365638117720309179;
+constexpr double Egamma = 0.577215664901532860606512090082402431042159335;
+
+constexpr auto DiffThreshold = 0.001;
+
+AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double, Threshold) {
+ return std::abs(Node.getValue().convertToDouble() - Value) < Threshold;
+}
+
+// We don't want to match uses of macros, such as
+//
+// auto PiHalved = MY_PI / 2;
+//
+// because a project might use defines for math constants.
+// Instead, the macro definition is matched and the value is exchanged there.
+// Hinting at replacing macro definitions with language constructs is done in
+// another check.
+AST_MATCHER(clang::Expr, isMathMacro) { return Node.getBeginLoc().isMacroID(); }
+
+AST_MATCHER_P(clang::QualType, hasUnqualifiedDesugaredType,
+ Matcher<clang::QualType>, InnerMatcher) {
+ return InnerMatcher.matches(Node->getCanonicalTypeUnqualified(), Finder,
+ Builder);
+}
+
+auto matchMathCall(const StringRef FunctionName,
+ const Matcher<clang::Expr> ArgumentMatcher) {
+ return callExpr(callee(functionDecl(hasName(FunctionName))),
+ hasArgument(0, ignoringImplicit(ArgumentMatcher)));
+}
+
+auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
+ return matchMathCall("sqrt", ArgumentMatcher);
+}
+
+// 'MatchDeclRefExprOrMacro' is used to differentiate matching expressions where
+// the value of anything used is near 'Val' and matching expressions where we
+// only care about the actual literal.
+// We don't want top-level matches to match a simple DeclRefExpr/macro that was
+// initialized with this value because projects might declare their own
+// constants (e.g. namespaced constants or macros) to be used. We don't want to
+// flag the use of these variables/constants, but modify the definition of the
+// variable or macro.
+//
+// example:
+// const auto e = 2.71828182; // std::numbers::e
+// ^^^^^^^^^^
+// match here
+//
+// auto use = e / 2;
+// ^
+// don't match this as a top-level match, this would create noise
+//
+// auto use2 = log2(e); // std::numbers::log2e
+// ^^^^^^^
+// match here, matcher needs to check the initialization
+// of e to match log2e
+//
+// Therefore, all top-level matcher set MatchDeclRefExprOrMacro to false
+auto matchFloatValueNear(const double Val,
+ const bool MatchDeclRefExprOrMacro = true) {
+ const auto FloatVal = floatLiteral(near(Val, DiffThreshold));
+ if (!MatchDeclRefExprOrMacro) {
+ return expr(unless(isMathMacro()), ignoringImplicit(FloatVal));
+ }
+
+ const auto Dref = declRefExpr(to(varDecl(
+ anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))),
+ hasInitializer(FloatVal))));
+ return expr(ignoringImplicit(anyOf(FloatVal, Dref)));
+}
+
+auto matchValue(const int64_t ValInt) {
+ const auto Int2 = integerLiteral(equals(ValInt));
+ const auto Float2 = matchFloatValueNear(static_cast<double>(ValInt));
+ const auto Dref = declRefExpr(to(varDecl(
+ anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))),
+ hasInitializer(expr(ignoringImplicit(anyOf(Int2, Float2)))))));
+ return expr(ignoringImplicit(anyOf(Int2, Float2, Dref)));
+}
+
+auto match1Div(const Matcher<clang::Expr> Match) {
+ return binaryOperator(hasOperatorName("/"), hasLHS(matchValue(1)),
+ hasRHS(ignoringImplicit(Match)));
+}
+
+auto matchEuler() {
+ return expr(
+ anyOf(matchFloatValueNear(Euler), matchMathCall("exp", matchValue(1))));
+}
+auto matchEulerTopLevel() {
+ return expr(anyOf(matchFloatValueNear(Euler, false),
+ matchMathCall("exp", matchValue(1))));
+}
+
+auto matchLog2Euler() {
+ return expr(anyOf(matchFloatValueNear(llvm::numbers::log2e, false),
+ matchMathCall("log2", matchEuler())));
+}
+
+auto matchLog10Euler() {
+ return expr(anyOf(matchFloatValueNear(llvm::numbers::log10e, false),
+ matchMathCall("log10", matchEuler())));
+}
+
+auto matchPi() { return matchFloatValueNear(Pi); }
+auto matchPiTopLevel() { return matchFloatValueNear(Pi, false); }
+
+auto matchEgamma() { return matchFloatValueNear(Egamma, false); }
+
+auto matchInvPi() {
+ return expr(
+ anyOf(matchFloatValueNear(llvm::numbers::inv_pi), match1Div(matchPi())));
+}
+
+auto matchInvSqrtPi() {
+ return expr(anyOf(matchFloatValueNear(llvm::numbers::inv_sqrtpi, false),
+ match1Div(matchSqrt(matchPi()))));
+}
+
+auto matchLn2() {
+ return expr(anyOf(matchFloatValueNear(llvm::numbers::ln2, false),
+ matchMathCall("log", ignoringImplicit(matchValue(2)))));
+}
+
+auto machterLn10() {
+ return expr(anyOf(matchFloatValueNear(llvm::numbers::ln10, false),
+ matchMathCall("log", ignoringImplicit(matchValue(10)))));
+}
+
+auto matchSqrt2() {
+ return expr(anyOf(matchFloatValueNear(llvm::numbers::sqrt2, false),
+ matchSqrt(matchValue(2))));
+}
+
+auto matchSqrt3() {
+ return expr(anyOf(matchFloatValueNear(llvm::numbers::sqrt3, false),
+ matchSqrt(matchValue(3))));
+}
+
+auto matchInvSqrt3() {
+ return expr(anyOf(matchFloatValueNear(llvm::numbers::inv_sqrt3, false),
+ match1Div(matchSqrt(matchValue(3)))));
+}
+
+auto matchPhi() {
+ const auto PhiFormula = binaryOperator(
+ hasOperatorName("/"),
+ hasLHS(parenExpr(has(binaryOperator(
+ hasOperatorName("+"), hasEitherOperand(matchValue(1)),
+ hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
+ hasRHS(matchValue(2)));
+ return expr(anyOf(PhiFormula, matchFloatValueNear(Phi)));
+}
+
+EditGenerator
+chainedIfBound(ASTEdit DefaultEdit,
+ llvm::SmallVector<std::pair<StringRef, ASTEdit>, 2> Edits) {
+ return [Edits = std::move(Edits), DefaultEdit = std::move(DefaultEdit)](
+ const MatchFinder::MatchResult &Result) {
+ auto &Map = Result.Nodes.getMap();
+ for (const auto &[Id, EditOfId] : Edits) {
+ if (Map.find(Id) != Map.end()) {
+ return edit(EditOfId)(Result);
+ }
+ }
+ return edit(DefaultEdit)(Result);
+ };
+}
+
+RewriteRuleWith<std::string> makeRule(const Matcher<clang::Stmt> Matcher,
+ const StringRef Constant) {
+ static const auto AddNumbersInclude =
+ addInclude("numbers", clang::transformer::IncludeFormat::Angled);
+
+ const auto DefaultEdit = changeTo(cat("std::numbers::", Constant));
+ const auto FloatEdit = changeTo(cat("std::numbers::", Constant, "_v<float>"));
+ const auto LongDoubleEdit =
+ changeTo(cat("std::numbers::", Constant, "_v<long double>"));
+
+ const auto EditRules = chainedIfBound(
+ DefaultEdit, {{"float", FloatEdit}, {"long double", LongDoubleEdit}});
+
+ return makeRule(
+ expr(Matcher,
+ hasType(qualType(hasCanonicalType(hasUnqualifiedDesugaredType(anyOf(
+ qualType(asString("float")).bind("float"),
+ qualType(asString("double")),
+ qualType(asString("long double")).bind("long double"))))))),
+ flattenVector({edit(AddNumbersInclude), EditRules}),
+ cat("prefer std::numbers math constant"));
+}
+
+/*
+ List of all math constants
+ + e
+ + log2e
+ + log10e
+ + pi
+ + inv_pi
+ + inv_sqrtpi
+ + ln2
+ + ln10
+ + sqrt2
+ + sqrt3
+ + inv_sqrt3
+ + egamma
+ + phi
+*/
+
+RewriteRuleWith<std::string> makeRewriteRule() {
+ return applyFirst({
+ makeRule(matchLog2Euler(), "log2e"),
+ makeRule(matchLog10Euler(), "log10e"),
+ makeRule(matchEulerTopLevel(), "e"),
+ makeRule(matchEgamma(), "egamma"),
+ makeRule(matchInvSqrtPi(), "inv_sqrtpi"),
+ makeRule(matchInvPi(), "inv_pi"),
+ makeRule(matchPiTopLevel(), "pi"),
+ makeRule(matchLn2(), "ln2"),
+ makeRule(machterLn10(), "ln10"),
+ makeRule(matchSqrt2(), "sqrt2"),
+ makeRule(matchInvSqrt3(), "inv_sqrt3"),
+ makeRule(matchSqrt3(), "sqrt3"),
+ makeRule(matchPhi(), "phi"),
+ });
+}
+
+class MathConstantMacroCallback : public clang::PPCallbacks {
+public:
+ explicit MathConstantMacroCallback(
+ clang::tidy::modernize::UseStdNumbersCheck *Check)
+ : Check{Check} {};
+
+ void MacroDefined(const clang::Token & /*MacroNameTok*/,
+ const clang::MacroDirective *MD) override {
+ for (const auto &Tok : MD->getDefinition().getMacroInfo()->tokens()) {
+ if (!Tok.is(clang::tok::numeric_constant)) {
+ continue;
+ }
+
+ const auto Definition =
+ llvm::StringRef{Tok.getLiteralData(), Tok.getLength()};
+ double Value{};
+ Definition.getAsDouble(Value);
+
+ const auto IsNear = [](const auto Lhs, const auto Rhs) {
+ return std::abs(Lhs - Rhs) < DiffThreshold;
+ };
+
+ if (IsNear(Value, llvm::numbers::log2e)) {
+ reportDiag(Tok, "std::numbers::log2e");
+ return;
+ }
+ if (IsNear(Value, llvm::numbers::log10e)) {
+ reportDiag(Tok, "std::numbers::log10e");
+ return;
+ }
+ if (IsNear(Value, llvm::numbers::e)) {
+ reportDiag(Tok, "std::numbers::e");
+ return;
+ }
+ if (IsNear(Value, llvm::numbers::egamma)) {
+ reportDiag(Tok, "std::numbers::egamma");
+ return;
+ }
+ if (IsNear(Value, llvm::numbers::inv_sqrtpi)) {
+ reportDiag(Tok, "std::numbers::inv_sqrtpi");
+ return;
+ }
+ if (IsNear(Value, llvm::numbers::inv_pi)) {
+ reportDiag(Tok, "std::numbers::inv_pi");
+ return;
+ }
+ if (IsNear(Value, llvm::numbers::pi)) {
+ reportDiag(Tok, "std::numbers::pi");
+ return;
+ }
+ if (IsNear(Value, llvm::numbers::ln2)) {
+ reportDiag(Tok, "std::numbers::ln2");
+ return;
+ }
+ if (IsNear(Value, llvm::numbers::ln10)) {
+ reportDiag(Tok, "std::numbers::ln10");
+ return;
+ }
+ if (IsNear(Value, llvm::numbers::sqrt2)) {
+ reportDiag(Tok, "std::numbers::sqrt2");
+ return;
+ }
+ if (IsNear(Value, llvm::numbers::inv_sqrt3)) {
+ reportDiag(Tok, "std::numbers::inv_sqrt3");
+ return;
+ }
+ if (IsNear(Value, llvm::numbers::sqrt3)) {
+ reportDiag(Tok, "std::numbers::sqrt3");
+ return;
+ }
+ if (IsNear(Value, llvm::numbers::phi)) {
+ reportDiag(Tok, "std::numbers::phi");
+ return;
+ }
+ }
+ }
+
+private:
+ void reportDiag(const clang::Token &Tok, const llvm::StringRef Constant) {
+ Check->diag(Tok.getLocation(), "prefer math constant")
+ << clang::FixItHint::CreateReplacement(
+ clang::SourceRange(Tok.getLocation(), Tok.getLastLoc()),
+ Constant);
+ }
+
+ clang::tidy::modernize::UseStdNumbersCheck *Check{};
+};
+} // namespace
+
+namespace clang::tidy::modernize {
+UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name,
+ ClangTidyContext *const Context)
+ : TransformerClangTidyCheck(Name, Context) {
+ setRule(makeRewriteRule());
+}
+
+void UseStdNumbersCheck::registerPPCallbacks(const SourceManager &SM,
+ Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) {
+ utils::TransformerClangTidyCheck::registerPPCallbacks(SM, PP,
+ ModuleExpanderPP);
+ PP->addPPCallbacks(std::make_unique<MathConstantMacroCallback>(this));
+}
+} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
new file mode 100644
index 0000000000000..5598d533a3ea7
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
@@ -0,0 +1,37 @@
+//===--- UseStdNumbersCheck.h - clang-tidy ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDNUMBERSCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDNUMBERSCHECK_H
+
+#include "../utils/TransformerClangTidyCheck.h"
+
+namespace clang::tidy::modernize {
+
+/// Finds constants and function calls to math functions that can be replaced
+/// with c++20's mathematical constants ('numbers' header). Does not match the
+/// use of variables or macros with that value and instead offers a replacement
+/// at the definition of said variables and macros.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-numbers.html
+class UseStdNumbersCheck : public utils::TransformerClangTidyCheck {
+public:
+ UseStdNumbersCheck(StringRef Name, ClangTidyContext *Context);
+
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+ return LangOpts.CPlusPlus20;
+ }
+
+ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) override;
+};
+
+} // namespace clang::tidy::modernize
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDNUMBERSCHECK_H
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 6d5f49dc06254..40f78d06d5af2 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -186,6 +186,12 @@ New checks
Replace ``enable_if`` with C++20 requires clauses.
+- New :doc:`modernize-use-std-numbers
+ <clang-tidy/checks/modernize/use-std-numbers>` check.
+
+ Finds constants and function calls to math functions that can be replaced
+ with c++20's mathematical constants ('numbers' header).
+
- New :doc:`performance-enum-size
<clang-tidy/checks/performance/enum-size>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 6f987ba1672e3..e753562994f74 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -292,6 +292,7 @@ Clang-Tidy Checks
:doc:`modernize-use-noexcept <modernize/use-noexcept>`, "Yes"
:doc:`modernize-use-nullptr <modernize/use-nullptr>`, "Yes"
:doc:`modernize-use-override <modernize/use-override>`, "Yes"
+ :doc:`modernize-use-std-numbers <modernize/use-std-numbers>`, "Yes"
:doc:`modernize-use-std-print <modernize/use-std-print>`, "Yes"
:doc:`modernize-use-trailing-return-type <modernize/use-trailing-return-type>`, "Yes"
:doc:`modernize-use-transparent-functors <modernize/use-transparent-functors>`, "Yes"
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
new file mode 100644
index 0000000000000..7911f2f7f857b
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -0,0 +1,25 @@
+.. title:: clang-tidy - modernize-use-std-numbers
+
+modernize-use-std-numbers
+=========================
+
+This check finds constants and function calls to math functions that can be replaced
+with c++20's mathematical constants ('numbers' header) and offers fixit-hints.
+Does not match the use of variables or macros with that value and instead, offers a replacement
+at the definition of said variables and macros.
+
+.. code-block:: c++
+ double sqrt(double);
+ double log(double);
+
+ #define MY_PI 3.1415926 // #define MY_PI std::numbers::pi
+
+ void foo() {
+ const double Pi = 3.141592653589; // const double Pi = std::numbers::pi
+ const auto Use = Pi / 2; // no match for Pi
+ static constexpr double Euler = 2.7182818; // static constexpr double Euler = std::numbers::e;
+
+ log2(exp(1)); // std::numbers::log2e;
+ log2(Euler); // std::numbers::log2e;
+ 1 / sqrt(MY_PI); // std::numbers::inv_sqrtpi;
+ }
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
new file mode 100644
index 0000000000000..2ba0525f38306
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -0,0 +1,205 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-std-numbers %t
+
+// CHECK-FIXES: #include <numbers>
+
+namespace bar {
+ double sqrt(double Arg);
+ float sqrt(float Arg);
+ template <typename T>
+ auto sqrt(T val) { return sqrt(static_cast<double>(val)); }
+
+ static constexpr double e = 2.718281828459045235360287471352662497757247093;
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr double e = std::numbers::e;
+}
+
+double exp(double Arg);
+double log(double Arg);
+double log2(double Arg);
+double log10(double Arg);
+
+template<typename T>
+void sink(T&&) { }
+
+#define MY_PI 3.1415926
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer math constant [modernize-use-std-numbers]
+// CHECK-FIXES: #define MY_PI std::numbers::pi
+#define MY_PI2 static_cast<float>(3.1415926)
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers]
+// CHECK-FIXES: #define MY_PI2 static_cast<float>(std::numbers::pi)
+
+#define INV_SQRT3 1 / bar::sqrt(3)
+
+void foo(){
+ static constexpr double Pi = 3.1415926;
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr double Pi = std::numbers::pi;
+
+ static constexpr double Euler = 2.7182818;
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr double Euler = std::numbers::e;
+
+ static constexpr double Phi = 1.6180339;
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr double Phi = std::numbers::phi;
+
+ static constexpr double PiCopy = Pi;
+ static constexpr double PiDefine = MY_PI;
+
+ // not close enough to match value (DiffThreshold)
+ static constexpr double Pi2 = 3.14;
+ static constexpr double Euler2 = 2.71;
+ static constexpr double Phi2 = 1.61;
+
+ static constexpr double Pi3 = 3.1415926L;
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr double Pi3 = std::numbers::pi;
+
+ static constexpr double Euler3 = 2.7182818L;
+ // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr double Euler3 = std::numbers::e;
+
+ static constexpr double Phi3 = 1.6180339L;
+ // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr double Phi3 = std::numbers::phi;
+
+ static constexpr long double Pi4 = 3.1415926L;
+ // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr long double Pi4 = std::numbers::pi_v<long double>;
+
+ static constexpr long double Euler4 = 2.7182818L;
+ // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr long double Euler4 = std::numbers::e_v<long double>;
+
+ static constexpr long double Phi4 = 1.6180339L;
+ // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
+
+ using my_float = const float;
+ static constexpr my_float Actually2MyFloat = 2;
+ bar::sqrt(Actually2MyFloat);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::sqrt2_v<float>;
+
+ constexpr static auto One = 1;
+ constexpr static auto Two = 2;
+
+ bar::sqrt(2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::sqrt2;
+
+ bar::sqrt(Two);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::sqrt2;
+
+ bar::sqrt(2.0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::sqrt2;
+
+ auto Not2 = 2;
+ Not2 = 42;
+ bar::sqrt(Not2);
+
+ const auto Actually2 = 2;
+ bar::sqrt(Actually2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::sqrt2;
+
+ exp(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::e;
+
+ exp(One);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::e;
+
+ exp(1.00000000000001);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::e;
+
+ log2(exp(1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::log2e;
+
+ log2(Euler);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::log2e;
+
+ log2(bar::e);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::log2e;
+
+ auto log2e = 1.4426950;
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: auto log2e = std::numbers::log2e;
+
+ log10(exp(1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::log10e;
+
+ log10(Euler);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::log10e;
+
+ log10(bar::e);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::log10e;
+
+ auto log10e = .434294;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: auto log10e = std::numbers::log10e;
+
+ auto egamma = 0.5772156 * 42;
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: auto egamma = std::numbers::egamma * 42;
+
+ sink(1 / Pi);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: sink(std::numbers::inv_pi);
+
+ sink(1 / bar::sqrt(Pi));
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
+
+ sink(1 / bar::sqrt(MY_PI));
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
+
+
+ log(2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::ln2;
+
+ log(10);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::ln10;
+
+ bar::sqrt(2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::sqrt2;
+
+ sink(1 / bar::sqrt(3));
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
+
+ bar::sqrt(3);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::sqrt3;
+
+ auto phi = 1.6180339;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: auto phi = std::numbers::phi;
+
+ sink((42 + bar::sqrt(5)) / 2);
+
+ sink((1 + bar::sqrt(5)) / 2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: sink(std::numbers::phi);
+
+ sink((bar::sqrt(5.0F) + 1) / 2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: sink(std::numbers::phi_v<float>);
+}
>From 46c5a1e92dc4e7c3f300f88326284abc54f42c80 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 16 Sep 2023 21:19:10 +0200
Subject: [PATCH 02/44] fix lexicographical ordering in some places after
rename
---
clang-tools-extra/clang-tidy/modernize/CMakeLists.txt | 2 +-
clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index d82353d74fbd0..b254d340c4e85 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -16,7 +16,6 @@ add_clang_library(clangTidyModernizeModule
MakeSharedCheck.cpp
MakeSmartPtrCheck.cpp
MakeUniqueCheck.cpp
- UseStdNumbersCheck.cpp
ModernizeTidyModule.cpp
PassByValueCheck.cpp
RawStringLiteralCheck.cpp
@@ -39,6 +38,7 @@ add_clang_library(clangTidyModernizeModule
UseNoexceptCheck.cpp
UseNullptrCheck.cpp
UseOverrideCheck.cpp
+ UseStdNumbersCheck.cpp
UseStdPrintCheck.cpp
UseTrailingReturnTypeCheck.cpp
UseTransparentFunctorsCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 73584e20166f6..4f33db5b741a7 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -18,7 +18,6 @@
#include "MacroToEnumCheck.h"
#include "MakeSharedCheck.h"
#include "MakeUniqueCheck.h"
-#include "UseStdNumbersCheck.h"
#include "PassByValueCheck.h"
#include "RawStringLiteralCheck.h"
#include "RedundantVoidArgCheck.h"
@@ -40,6 +39,7 @@
#include "UseNoexceptCheck.h"
#include "UseNullptrCheck.h"
#include "UseOverrideCheck.h"
+#include "UseStdNumbersCheck.h"
#include "UseStdPrintCheck.h"
#include "UseTrailingReturnTypeCheck.h"
#include "UseTransparentFunctorsCheck.h"
>From 4ab522e8e532eb3bc63e0b1726075994c01eab07 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sun, 17 Sep 2023 11:44:58 +0200
Subject: [PATCH 03/44] address comments
- changed ReleaseNotes and first sentence of the check documentation
by removing parentheses around the numbers header and noted that
fix-it hints are emitted
---
clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 2 +-
clang-tools-extra/docs/ReleaseNotes.rst | 3 ++-
.../docs/clang-tidy/checks/modernize/use-std-numbers.rst | 4 ++--
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index c23dc6671013b..f4bcfb903ad08 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -1,4 +1,4 @@
-//===--- UseStdNumbersCheck.cpp - clang_tidy -------------------------===//
+//===--- UseStdNumbersCheck.cpp - clang_tidy ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 40f78d06d5af2..6e9a9cb4aacdf 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -190,7 +190,8 @@ New checks
<clang-tidy/checks/modernize/use-std-numbers>` check.
Finds constants and function calls to math functions that can be replaced
- with c++20's mathematical constants ('numbers' header).
+ with c++20's mathematical constants from the ``numbers`` header and
+ offers fix-it hints.
- New :doc:`performance-enum-size
<clang-tidy/checks/performance/enum-size>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
index 7911f2f7f857b..ec443123334f5 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -3,8 +3,8 @@
modernize-use-std-numbers
=========================
-This check finds constants and function calls to math functions that can be replaced
-with c++20's mathematical constants ('numbers' header) and offers fixit-hints.
+Finds constants and function calls to math functions that can be replaced
+with c++20's mathematical constants from the ``numbers`` header and offers fix-it hints.
Does not match the use of variables or macros with that value and instead, offers a replacement
at the definition of said variables and macros.
>From 0f63f076a4879e1bccb9a85959dc60d3739a0880 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sun, 17 Sep 2023 18:54:56 +0200
Subject: [PATCH 04/44] update descriptions slightly
- update check description in header to reflect release notes description
- add comma
---
.../clang-tidy/modernize/UseStdNumbersCheck.h | 7 ++++---
.../docs/clang-tidy/checks/modernize/use-std-numbers.rst | 2 +-
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
index 5598d533a3ea7..9fc98a1892b29 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
@@ -14,9 +14,10 @@
namespace clang::tidy::modernize {
/// Finds constants and function calls to math functions that can be replaced
-/// with c++20's mathematical constants ('numbers' header). Does not match the
-/// use of variables or macros with that value and instead offers a replacement
-/// at the definition of said variables and macros.
+/// with c++20's mathematical constants from the ``numbers`` header and
+/// offers fix-it hints.
+/// Does not match the use of variables or macros with that value, and instead,
+/// offers a replacement at the definition of said variables and macros.
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-numbers.html
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
index ec443123334f5..613db21435177 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -5,7 +5,7 @@ modernize-use-std-numbers
Finds constants and function calls to math functions that can be replaced
with c++20's mathematical constants from the ``numbers`` header and offers fix-it hints.
-Does not match the use of variables or macros with that value and instead, offers a replacement
+Does not match the use of variables or macros with that value, and instead, offers a replacement
at the definition of said variables and macros.
.. code-block:: c++
>From 5820525955e3fd8c655665e81dacd9738ede30b5 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Mon, 18 Sep 2023 22:15:42 +0200
Subject: [PATCH 05/44] fixup update of warning message
---
.../modernize/UseStdNumbersCheck.cpp | 2 +-
.../checkers/modernize/use-std-numbers.cpp | 86 +++++++++----------
2 files changed, 44 insertions(+), 44 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index f4bcfb903ad08..bce0ab2117a48 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -350,7 +350,7 @@ class MathConstantMacroCallback : public clang::PPCallbacks {
private:
void reportDiag(const clang::Token &Tok, const llvm::StringRef Constant) {
- Check->diag(Tok.getLocation(), "prefer math constant")
+ Check->diag(Tok.getLocation(), "prefer std::numbers math constant")
<< clang::FixItHint::CreateReplacement(
clang::SourceRange(Tok.getLocation(), Tok.getLastLoc()),
Constant);
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 2ba0525f38306..bc9ecdaf8bc92 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -9,7 +9,7 @@ namespace bar {
auto sqrt(T val) { return sqrt(static_cast<double>(val)); }
static constexpr double e = 2.718281828459045235360287471352662497757247093;
- // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double e = std::numbers::e;
}
@@ -22,25 +22,25 @@ template<typename T>
void sink(T&&) { }
#define MY_PI 3.1415926
-// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer math constant [modernize-use-std-numbers]
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: #define MY_PI std::numbers::pi
#define MY_PI2 static_cast<float>(3.1415926)
-// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers]
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: #define MY_PI2 static_cast<float>(std::numbers::pi)
#define INV_SQRT3 1 / bar::sqrt(3)
void foo(){
static constexpr double Pi = 3.1415926;
- // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Pi = std::numbers::pi;
static constexpr double Euler = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Euler = std::numbers::e;
static constexpr double Phi = 1.6180339;
- // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Phi = std::numbers::phi;
static constexpr double PiCopy = Pi;
@@ -52,48 +52,48 @@ void foo(){
static constexpr double Phi2 = 1.61;
static constexpr double Pi3 = 3.1415926L;
- // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Pi3 = std::numbers::pi;
static constexpr double Euler3 = 2.7182818L;
- // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Euler3 = std::numbers::e;
static constexpr double Phi3 = 1.6180339L;
- // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Phi3 = std::numbers::phi;
static constexpr long double Pi4 = 3.1415926L;
- // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr long double Pi4 = std::numbers::pi_v<long double>;
static constexpr long double Euler4 = 2.7182818L;
- // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr long double Euler4 = std::numbers::e_v<long double>;
static constexpr long double Phi4 = 1.6180339L;
- // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
using my_float = const float;
static constexpr my_float Actually2MyFloat = 2;
bar::sqrt(Actually2MyFloat);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2_v<float>;
constexpr static auto One = 1;
constexpr static auto Two = 2;
bar::sqrt(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
bar::sqrt(Two);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
bar::sqrt(2.0);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
auto Not2 = 2;
@@ -102,104 +102,104 @@ void foo(){
const auto Actually2 = 2;
bar::sqrt(Actually2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
exp(1);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::e;
exp(One);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::e;
exp(1.00000000000001);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::e;
log2(exp(1));
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
log2(Euler);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
log2(bar::e);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
auto log2e = 1.4426950;
- // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: auto log2e = std::numbers::log2e;
log10(exp(1));
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log10e;
log10(Euler);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log10e;
log10(bar::e);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log10e;
auto log10e = .434294;
- // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: auto log10e = std::numbers::log10e;
auto egamma = 0.5772156 * 42;
- // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: auto egamma = std::numbers::egamma * 42;
sink(1 / Pi);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_pi);
sink(1 / bar::sqrt(Pi));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
sink(1 / bar::sqrt(MY_PI));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
log(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::ln2;
log(10);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::ln10;
bar::sqrt(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
sink(1 / bar::sqrt(3));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrt3);
bar::sqrt(3);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt3;
auto phi = 1.6180339;
- // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: auto phi = std::numbers::phi;
sink((42 + bar::sqrt(5)) / 2);
sink((1 + bar::sqrt(5)) / 2);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::phi);
sink((bar::sqrt(5.0F) + 1) / 2);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::phi_v<float>);
}
>From 6a75cbe8cfcb916f50cd6edc7f52f533716b9e8b Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Mon, 25 Sep 2023 12:42:21 +0200
Subject: [PATCH 06/44] rename isMathMacro to isMacro
---
clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index bce0ab2117a48..7fa4d00d45520 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -60,7 +60,7 @@ AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double, Threshold) {
// Instead, the macro definition is matched and the value is exchanged there.
// Hinting at replacing macro definitions with language constructs is done in
// another check.
-AST_MATCHER(clang::Expr, isMathMacro) { return Node.getBeginLoc().isMacroID(); }
+AST_MATCHER(clang::Expr, isMacro) { return Node.getBeginLoc().isMacroID(); }
AST_MATCHER_P(clang::QualType, hasUnqualifiedDesugaredType,
Matcher<clang::QualType>, InnerMatcher) {
@@ -106,7 +106,7 @@ auto matchFloatValueNear(const double Val,
const bool MatchDeclRefExprOrMacro = true) {
const auto FloatVal = floatLiteral(near(Val, DiffThreshold));
if (!MatchDeclRefExprOrMacro) {
- return expr(unless(isMathMacro()), ignoringImplicit(FloatVal));
+ return expr(unless(isMacro()), ignoringImplicit(FloatVal));
}
const auto Dref = declRefExpr(to(varDecl(
>From 670c9e0e5a0a925d28ae5027d3e8c4b61eacf4af Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Mon, 25 Sep 2023 13:14:53 +0200
Subject: [PATCH 07/44] add tests for uses in templates
- dont match in template instantiations
---
.../modernize/UseStdNumbersCheck.cpp | 2 +-
.../checkers/modernize/use-std-numbers.cpp | 160 ++++++++++++++++++
2 files changed, 161 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 7fa4d00d45520..db92a1f50b7bc 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -227,7 +227,7 @@ RewriteRuleWith<std::string> makeRule(const Matcher<clang::Stmt> Matcher,
DefaultEdit, {{"float", FloatEdit}, {"long double", LongDoubleEdit}});
return makeRule(
- expr(Matcher,
+ expr(Matcher, unless(isInTemplateInstantiation()),
hasType(qualType(hasCanonicalType(hasUnqualifiedDesugaredType(anyOf(
qualType(asString("float")).bind("float"),
qualType(asString("double")),
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index bc9ecdaf8bc92..8914ffc1e05f4 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -203,3 +203,163 @@ void foo(){
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::phi_v<float>);
}
+
+
+
+template <typename T>
+void baz(){
+ static constexpr T Pi = 3.1415926;
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr T Pi = std::numbers::pi;
+
+ static constexpr T Euler = 2.7182818;
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr T Euler = std::numbers::e;
+
+ static constexpr T Phi = 1.6180339;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr T Phi = std::numbers::phi;
+
+ static constexpr T PiCopy = Pi;
+ static constexpr T PiDefine = MY_PI;
+
+ // not close enough to match value (DiffThreshold)
+ static constexpr T Pi2 = 3.14;
+ static constexpr T Euler2 = 2.71;
+ static constexpr T Phi2 = 1.61;
+
+ static constexpr T Pi3 = 3.1415926L;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr T Pi3 = std::numbers::pi_v<long double>;
+
+ static constexpr T Euler3 = 2.7182818L;
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr T Euler3 = std::numbers::e_v<long double>;
+
+ static constexpr T Phi3 = 1.6180339L;
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr T Phi3 = std::numbers::phi_v<long double>;
+
+ using my_float = const float;
+ static constexpr my_float Actually2MyFloat = 2;
+ bar::sqrt(Actually2MyFloat);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::sqrt2_v<float>;
+
+ constexpr static T One = 1;
+ constexpr static T Two = 2;
+
+ bar::sqrt(2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::sqrt2;
+
+ bar::sqrt(Two);
+
+ bar::sqrt(2.0);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::sqrt2;
+
+ T Not2 = 2;
+ Not2 = 42;
+ bar::sqrt(Not2);
+
+ const T Actually2 = 2;
+ bar::sqrt(Actually2);
+
+ exp(1);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::e;
+
+ exp(One);
+
+ exp(1.00000000000001);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::e;
+
+ log2(exp(1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::log2e;
+
+ log2(Euler);
+
+ log2(bar::e);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::log2e;
+
+ T log2e = 1.4426950;
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: T log2e = std::numbers::log2e;
+
+ log10(exp(1));
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::log10e;
+
+ log10(Euler);
+
+ log10(bar::e);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::log10e;
+
+ T log10e = .434294;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: T log10e = std::numbers::log10e;
+
+ T egamma = 0.5772156 * 42;
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: T egamma = std::numbers::egamma * 42;
+
+ sink(1 / Pi);
+
+ sink(1 / bar::sqrt(Pi));
+
+ sink(1 / bar::sqrt(MY_PI));
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
+
+
+ log(2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::ln2;
+
+ log(10);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::ln10;
+
+ bar::sqrt(2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::sqrt2;
+
+ sink(1 / bar::sqrt(3));
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
+
+ bar::sqrt(3);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::sqrt3;
+
+ T phi = 1.6180339;
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: T phi = std::numbers::phi;
+
+ sink((42 + bar::sqrt(5)) / 2);
+
+ sink((1 + bar::sqrt(5)) / 2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: sink(std::numbers::phi);
+
+ sink((bar::sqrt(5.0F) + 1) / 2);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: sink(std::numbers::phi_v<float>);
+}
+
+template <typename T>
+void foobar(){
+ const T Two = 2;
+ bar::sqrt(Two);
+}
+void use_foobar() {
+ foobar<float>();
+}
>From 2c90f626a6426b1eafa65d5f942d40f6a11ed5a5 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Mon, 25 Sep 2023 13:15:04 +0200
Subject: [PATCH 08/44] fix matcher names
---
.../clang-tidy/modernize/UseStdNumbersCheck.cpp | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index db92a1f50b7bc..8b3fa976b74d4 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -104,24 +104,24 @@ auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
// Therefore, all top-level matcher set MatchDeclRefExprOrMacro to false
auto matchFloatValueNear(const double Val,
const bool MatchDeclRefExprOrMacro = true) {
- const auto FloatVal = floatLiteral(near(Val, DiffThreshold));
+ const auto Float = floatLiteral(near(Val, DiffThreshold));
if (!MatchDeclRefExprOrMacro) {
- return expr(unless(isMacro()), ignoringImplicit(FloatVal));
+ return expr(unless(isMacro()), ignoringImplicit(Float));
}
const auto Dref = declRefExpr(to(varDecl(
anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))),
- hasInitializer(FloatVal))));
- return expr(ignoringImplicit(anyOf(FloatVal, Dref)));
+ hasInitializer(Float))));
+ return expr(ignoringImplicit(anyOf(Float, Dref)));
}
auto matchValue(const int64_t ValInt) {
- const auto Int2 = integerLiteral(equals(ValInt));
- const auto Float2 = matchFloatValueNear(static_cast<double>(ValInt));
+ const auto Int = integerLiteral(equals(ValInt));
+ const auto Float = matchFloatValueNear(static_cast<double>(ValInt));
const auto Dref = declRefExpr(to(varDecl(
anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))),
- hasInitializer(expr(ignoringImplicit(anyOf(Int2, Float2)))))));
- return expr(ignoringImplicit(anyOf(Int2, Float2, Dref)));
+ hasInitializer(expr(ignoringImplicit(anyOf(Int, Float)))))));
+ return expr(ignoringImplicit(anyOf(Int, Float, Dref)));
}
auto match1Div(const Matcher<clang::Expr> Match) {
>From 8acc5e86e08012ca74cc9e0f43407b52844467a8 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 7 Oct 2023 17:58:15 +0200
Subject: [PATCH 09/44] fix name of custom matcher hasCanonicalTypeUnqualified
---
clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 8b3fa976b74d4..6fe31c43115ab 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -62,7 +62,7 @@ AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double, Threshold) {
// another check.
AST_MATCHER(clang::Expr, isMacro) { return Node.getBeginLoc().isMacroID(); }
-AST_MATCHER_P(clang::QualType, hasUnqualifiedDesugaredType,
+AST_MATCHER_P(clang::QualType, hasCanonicalTypeUnqualified,
Matcher<clang::QualType>, InnerMatcher) {
return InnerMatcher.matches(Node->getCanonicalTypeUnqualified(), Finder,
Builder);
@@ -228,7 +228,7 @@ RewriteRuleWith<std::string> makeRule(const Matcher<clang::Stmt> Matcher,
return makeRule(
expr(Matcher, unless(isInTemplateInstantiation()),
- hasType(qualType(hasCanonicalType(hasUnqualifiedDesugaredType(anyOf(
+ hasType(qualType(hasCanonicalType(hasCanonicalTypeUnqualified(anyOf(
qualType(asString("float")).bind("float"),
qualType(asString("double")),
qualType(asString("long double")).bind("long double"))))))),
>From 5e7e11f5dc0badcbd7fca8ff4fbea9a3e62c543b Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 7 Oct 2023 18:01:50 +0200
Subject: [PATCH 10/44] remove custom constants in favor of using llvm::numbers
for all
---
.../modernize/UseStdNumbersCheck.cpp | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 6fe31c43115ab..799b5cc2aaa81 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -41,11 +41,6 @@ using clang::transformer::flattenVector;
using clang::transformer::RewriteRuleWith;
using llvm::StringRef;
-constexpr double Pi = 3.141592653589793238462643383279502884197169399;
-constexpr double Euler = 2.718281828459045235360287471352662497757247093;
-constexpr double Phi = 1.618033988749894848204586834365638117720309179;
-constexpr double Egamma = 0.577215664901532860606512090082402431042159335;
-
constexpr auto DiffThreshold = 0.001;
AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double, Threshold) {
@@ -130,11 +125,11 @@ auto match1Div(const Matcher<clang::Expr> Match) {
}
auto matchEuler() {
- return expr(
- anyOf(matchFloatValueNear(Euler), matchMathCall("exp", matchValue(1))));
+ return expr(anyOf(matchFloatValueNear(llvm::numbers::e),
+ matchMathCall("exp", matchValue(1))));
}
auto matchEulerTopLevel() {
- return expr(anyOf(matchFloatValueNear(Euler, false),
+ return expr(anyOf(matchFloatValueNear(llvm::numbers::e, false),
matchMathCall("exp", matchValue(1))));
}
@@ -148,10 +143,10 @@ auto matchLog10Euler() {
matchMathCall("log10", matchEuler())));
}
-auto matchPi() { return matchFloatValueNear(Pi); }
-auto matchPiTopLevel() { return matchFloatValueNear(Pi, false); }
+auto matchPi() { return matchFloatValueNear(llvm::numbers::pi); }
+auto matchPiTopLevel() { return matchFloatValueNear(llvm::numbers::pi, false); }
-auto matchEgamma() { return matchFloatValueNear(Egamma, false); }
+auto matchEgamma() { return matchFloatValueNear(llvm::numbers::egamma, false); }
auto matchInvPi() {
return expr(
@@ -195,7 +190,7 @@ auto matchPhi() {
hasOperatorName("+"), hasEitherOperand(matchValue(1)),
hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
hasRHS(matchValue(2)));
- return expr(anyOf(PhiFormula, matchFloatValueNear(Phi)));
+ return expr(anyOf(PhiFormula, matchFloatValueNear(llvm::numbers::phi)));
}
EditGenerator
>From 44330fc5dd5eae24f42f7e07d8d3acccdc9252aa Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 7 Oct 2023 18:03:19 +0200
Subject: [PATCH 11/44] remove not needed argument for using a compile-time
constant
---
.../clang-tidy/modernize/UseStdNumbersCheck.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 799b5cc2aaa81..9e8863c91d0ff 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -43,8 +43,8 @@ using llvm::StringRef;
constexpr auto DiffThreshold = 0.001;
-AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double, Threshold) {
- return std::abs(Node.getValue().convertToDouble() - Value) < Threshold;
+AST_MATCHER_P(clang::FloatingLiteral, near, double, Value) {
+ return std::abs(Node.getValue().convertToDouble() - Value) < DiffThreshold;
}
// We don't want to match uses of macros, such as
@@ -99,7 +99,7 @@ auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
// Therefore, all top-level matcher set MatchDeclRefExprOrMacro to false
auto matchFloatValueNear(const double Val,
const bool MatchDeclRefExprOrMacro = true) {
- const auto Float = floatLiteral(near(Val, DiffThreshold));
+ const auto Float = floatLiteral(near(Val));
if (!MatchDeclRefExprOrMacro) {
return expr(unless(isMacro()), ignoringImplicit(Float));
}
>From 67c1d05538b846710ba04d4f973344b1755b51cd Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 7 Oct 2023 18:14:24 +0200
Subject: [PATCH 12/44] fix inv_pi and phi matchers matching uses of named
constants
---
.../clang-tidy/modernize/UseStdNumbersCheck.cpp | 7 ++++---
.../clang-tidy/checkers/modernize/use-std-numbers.cpp | 8 ++++++++
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 9e8863c91d0ff..2939a0f1d9ca7 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -149,8 +149,8 @@ auto matchPiTopLevel() { return matchFloatValueNear(llvm::numbers::pi, false); }
auto matchEgamma() { return matchFloatValueNear(llvm::numbers::egamma, false); }
auto matchInvPi() {
- return expr(
- anyOf(matchFloatValueNear(llvm::numbers::inv_pi), match1Div(matchPi())));
+ return expr(anyOf(matchFloatValueNear(llvm::numbers::inv_pi, false),
+ match1Div(matchPi())));
}
auto matchInvSqrtPi() {
@@ -190,7 +190,8 @@ auto matchPhi() {
hasOperatorName("+"), hasEitherOperand(matchValue(1)),
hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
hasRHS(matchValue(2)));
- return expr(anyOf(PhiFormula, matchFloatValueNear(llvm::numbers::phi)));
+ return expr(
+ anyOf(PhiFormula, matchFloatValueNear(llvm::numbers::phi, false)));
}
EditGenerator
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 8914ffc1e05f4..19efa3291ea36 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -75,6 +75,10 @@ void foo(){
// CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
+ static constexpr double InvPi = 1.0 / Pi;
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr double InvPi = std::numbers::inv_pi;
+
using my_float = const float;
static constexpr my_float Actually2MyFloat = 2;
bar::sqrt(Actually2MyFloat);
@@ -155,6 +159,8 @@ void foo(){
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: auto egamma = std::numbers::egamma * 42;
+ sink(InvPi);
+
sink(1 / Pi);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_pi);
@@ -193,6 +199,8 @@ void foo(){
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: auto phi = std::numbers::phi;
+ sink(Phi);
+
sink((42 + bar::sqrt(5)) / 2);
sink((1 + bar::sqrt(5)) / 2);
>From 2d01edc97131f66bdbe8fd45be3d85c7b8aaacb7 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 27 Oct 2023 23:00:58 +0200
Subject: [PATCH 13/44] change matches of macro defs to macro uses
- modernizes the usage of macros to the std::numbers constants
- removes PPCallback that failed CI
- change comments and docs
---
.../modernize/UseStdNumbersCheck.cpp | 112 ------------------
.../clang-tidy/modernize/UseStdNumbersCheck.h | 7 +-
.../checks/modernize/use-std-numbers.rst | 8 +-
.../checkers/modernize/use-std-numbers.cpp | 20 ++--
4 files changed, 19 insertions(+), 128 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 2939a0f1d9ca7..acbdcde06b329 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -14,12 +14,6 @@
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/TokenKinds.h"
-#include "clang/Lex/PPCallbacks.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/Token.h"
#include "clang/Tooling/Transformer/RewriteRule.h"
#include "clang/Tooling/Transformer/Stencil.h"
#include "llvm/ADT/StringRef.h"
@@ -47,16 +41,6 @@ AST_MATCHER_P(clang::FloatingLiteral, near, double, Value) {
return std::abs(Node.getValue().convertToDouble() - Value) < DiffThreshold;
}
-// We don't want to match uses of macros, such as
-//
-// auto PiHalved = MY_PI / 2;
-//
-// because a project might use defines for math constants.
-// Instead, the macro definition is matched and the value is exchanged there.
-// Hinting at replacing macro definitions with language constructs is done in
-// another check.
-AST_MATCHER(clang::Expr, isMacro) { return Node.getBeginLoc().isMacroID(); }
-
AST_MATCHER_P(clang::QualType, hasCanonicalTypeUnqualified,
Matcher<clang::QualType>, InnerMatcher) {
return InnerMatcher.matches(Node->getCanonicalTypeUnqualified(), Finder,
@@ -266,94 +250,6 @@ RewriteRuleWith<std::string> makeRewriteRule() {
makeRule(matchPhi(), "phi"),
});
}
-
-class MathConstantMacroCallback : public clang::PPCallbacks {
-public:
- explicit MathConstantMacroCallback(
- clang::tidy::modernize::UseStdNumbersCheck *Check)
- : Check{Check} {};
-
- void MacroDefined(const clang::Token & /*MacroNameTok*/,
- const clang::MacroDirective *MD) override {
- for (const auto &Tok : MD->getDefinition().getMacroInfo()->tokens()) {
- if (!Tok.is(clang::tok::numeric_constant)) {
- continue;
- }
-
- const auto Definition =
- llvm::StringRef{Tok.getLiteralData(), Tok.getLength()};
- double Value{};
- Definition.getAsDouble(Value);
-
- const auto IsNear = [](const auto Lhs, const auto Rhs) {
- return std::abs(Lhs - Rhs) < DiffThreshold;
- };
-
- if (IsNear(Value, llvm::numbers::log2e)) {
- reportDiag(Tok, "std::numbers::log2e");
- return;
- }
- if (IsNear(Value, llvm::numbers::log10e)) {
- reportDiag(Tok, "std::numbers::log10e");
- return;
- }
- if (IsNear(Value, llvm::numbers::e)) {
- reportDiag(Tok, "std::numbers::e");
- return;
- }
- if (IsNear(Value, llvm::numbers::egamma)) {
- reportDiag(Tok, "std::numbers::egamma");
- return;
- }
- if (IsNear(Value, llvm::numbers::inv_sqrtpi)) {
- reportDiag(Tok, "std::numbers::inv_sqrtpi");
- return;
- }
- if (IsNear(Value, llvm::numbers::inv_pi)) {
- reportDiag(Tok, "std::numbers::inv_pi");
- return;
- }
- if (IsNear(Value, llvm::numbers::pi)) {
- reportDiag(Tok, "std::numbers::pi");
- return;
- }
- if (IsNear(Value, llvm::numbers::ln2)) {
- reportDiag(Tok, "std::numbers::ln2");
- return;
- }
- if (IsNear(Value, llvm::numbers::ln10)) {
- reportDiag(Tok, "std::numbers::ln10");
- return;
- }
- if (IsNear(Value, llvm::numbers::sqrt2)) {
- reportDiag(Tok, "std::numbers::sqrt2");
- return;
- }
- if (IsNear(Value, llvm::numbers::inv_sqrt3)) {
- reportDiag(Tok, "std::numbers::inv_sqrt3");
- return;
- }
- if (IsNear(Value, llvm::numbers::sqrt3)) {
- reportDiag(Tok, "std::numbers::sqrt3");
- return;
- }
- if (IsNear(Value, llvm::numbers::phi)) {
- reportDiag(Tok, "std::numbers::phi");
- return;
- }
- }
- }
-
-private:
- void reportDiag(const clang::Token &Tok, const llvm::StringRef Constant) {
- Check->diag(Tok.getLocation(), "prefer std::numbers math constant")
- << clang::FixItHint::CreateReplacement(
- clang::SourceRange(Tok.getLocation(), Tok.getLastLoc()),
- Constant);
- }
-
- clang::tidy::modernize::UseStdNumbersCheck *Check{};
-};
} // namespace
namespace clang::tidy::modernize {
@@ -362,12 +258,4 @@ UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name,
: TransformerClangTidyCheck(Name, Context) {
setRule(makeRewriteRule());
}
-
-void UseStdNumbersCheck::registerPPCallbacks(const SourceManager &SM,
- Preprocessor *PP,
- Preprocessor *ModuleExpanderPP) {
- utils::TransformerClangTidyCheck::registerPPCallbacks(SM, PP,
- ModuleExpanderPP);
- PP->addPPCallbacks(std::make_unique<MathConstantMacroCallback>(this));
-}
} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
index 9fc98a1892b29..3cf2d9244cc81 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
@@ -16,8 +16,8 @@ namespace clang::tidy::modernize {
/// Finds constants and function calls to math functions that can be replaced
/// with c++20's mathematical constants from the ``numbers`` header and
/// offers fix-it hints.
-/// Does not match the use of variables or macros with that value, and instead,
-/// offers a replacement at the definition of said variables and macros.
+/// Does not match the use of variables with that value, and instead,
+/// offers a replacement at the definition of those variables.
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-numbers.html
@@ -28,9 +28,6 @@ class UseStdNumbersCheck : public utils::TransformerClangTidyCheck {
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return LangOpts.CPlusPlus20;
}
-
- void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
- Preprocessor *ModuleExpanderPP) override;
};
} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
index 613db21435177..5da01bd34eaf6 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -5,14 +5,15 @@ modernize-use-std-numbers
Finds constants and function calls to math functions that can be replaced
with c++20's mathematical constants from the ``numbers`` header and offers fix-it hints.
-Does not match the use of variables or macros with that value, and instead, offers a replacement
-at the definition of said variables and macros.
+Does not match the use of variables with that value, and instead,
+offers a replacement at the definition of those variables.
.. code-block:: c++
double sqrt(double);
double log(double);
+ void sink(auto&&) {}
- #define MY_PI 3.1415926 // #define MY_PI std::numbers::pi
+ #define MY_PI 3.1415926
void foo() {
const double Pi = 3.141592653589; // const double Pi = std::numbers::pi
@@ -22,4 +23,5 @@ at the definition of said variables and macros.
log2(exp(1)); // std::numbers::log2e;
log2(Euler); // std::numbers::log2e;
1 / sqrt(MY_PI); // std::numbers::inv_sqrtpi;
+ sink(MY_PI); // sink(std::numbers::pi);
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 19efa3291ea36..8fce42b901b1a 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -22,11 +22,6 @@ template<typename T>
void sink(T&&) { }
#define MY_PI 3.1415926
-// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-// CHECK-FIXES: #define MY_PI std::numbers::pi
-#define MY_PI2 static_cast<float>(3.1415926)
-// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
-// CHECK-FIXES: #define MY_PI2 static_cast<float>(std::numbers::pi)
#define INV_SQRT3 1 / bar::sqrt(3)
@@ -44,7 +39,9 @@ void foo(){
// CHECK-FIXES: static constexpr double Phi = std::numbers::phi;
static constexpr double PiCopy = Pi;
- static constexpr double PiDefine = MY_PI;
+ static constexpr double PiDefineFromMacro = MY_PI;
+ // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr double PiDefineFromMacro = std::numbers::pi;
// not close enough to match value (DiffThreshold)
static constexpr double Pi2 = 3.14;
@@ -171,9 +168,9 @@ void foo(){
sink(1 / bar::sqrt(MY_PI));
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
-
log(2);
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::ln2;
@@ -191,6 +188,10 @@ void foo(){
// CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrt3);
+ sink(INV_SQRT3);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
+
bar::sqrt(3);
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt3;
@@ -229,7 +230,9 @@ void baz(){
// CHECK-FIXES: static constexpr T Phi = std::numbers::phi;
static constexpr T PiCopy = Pi;
- static constexpr T PiDefine = MY_PI;
+ static constexpr T PiDefineFromMacro = MY_PI;
+ // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr T PiDefineFromMacro = std::numbers::pi;
// not close enough to match value (DiffThreshold)
static constexpr T Pi2 = 3.14;
@@ -324,6 +327,7 @@ void baz(){
sink(1 / bar::sqrt(MY_PI));
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
>From 040d67d3243186e05dc1b9589ceda993167101d2 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 27 Oct 2023 23:03:23 +0200
Subject: [PATCH 14/44] split matcher for float values
- removes the optional bool flag
- improves readability for matchers
- split the comment
---
.../modernize/UseStdNumbersCheck.cpp | 72 +++++++++----------
1 file changed, 33 insertions(+), 39 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index acbdcde06b329..98beab00a0181 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -8,6 +8,7 @@
#include "UseStdNumbersCheck.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
@@ -57,36 +58,30 @@ auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
return matchMathCall("sqrt", ArgumentMatcher);
}
-// 'MatchDeclRefExprOrMacro' is used to differentiate matching expressions where
-// the value of anything used is near 'Val' and matching expressions where we
-// only care about the actual literal.
-// We don't want top-level matches to match a simple DeclRefExpr/macro that was
-// initialized with this value because projects might declare their own
-// constants (e.g. namespaced constants or macros) to be used. We don't want to
-// flag the use of these variables/constants, but modify the definition of the
-// variable or macro.
+// Used for top-level matchers (i.e. the match that replaces Val with its
+// constant).
//
-// example:
-// const auto e = 2.71828182; // std::numbers::e
-// ^^^^^^^^^^
-// match here
+// E.g. The matcher of `std::numbers::pi` uses this matcher to look to
+// floatLiterals that have the value of pi.
//
-// auto use = e / 2;
-// ^
-// don't match this as a top-level match, this would create noise
+// We only care about the literal if the match is for a top-level match
+auto matchFloatLiteralNear(const double Val) {
+ return expr(ignoringImplicit(floatLiteral(near(Val))));
+}
+
+// Used for non-top-level matchers (i.e. matchers that are used as inner
+// matchers for top-level matchers).
//
-// auto use2 = log2(e); // std::numbers::log2e
-// ^^^^^^^
-// match here, matcher needs to check the initialization
-// of e to match log2e
+// E.g.: The matcher of `std::numbers::log2e` uses this matcher to check if `e`
+// of `log2(e)` is declared constant and initialized with the value for eulers
+// number.
//
-// Therefore, all top-level matcher set MatchDeclRefExprOrMacro to false
-auto matchFloatValueNear(const double Val,
- const bool MatchDeclRefExprOrMacro = true) {
+// Here, we do care about literals and about DeclRefExprs to variable
+// declarations that are constant and initialized with `Val`. This allows
+// top-level matchers to see through declared constants for their inner matches
+// like the `std::numbers::log2e` matcher.
+auto matchFloatValueNear(const double Val) {
const auto Float = floatLiteral(near(Val));
- if (!MatchDeclRefExprOrMacro) {
- return expr(unless(isMacro()), ignoringImplicit(Float));
- }
const auto Dref = declRefExpr(to(varDecl(
anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))),
@@ -113,57 +108,57 @@ auto matchEuler() {
matchMathCall("exp", matchValue(1))));
}
auto matchEulerTopLevel() {
- return expr(anyOf(matchFloatValueNear(llvm::numbers::e, false),
+ return expr(anyOf(matchFloatLiteralNear(llvm::numbers::e),
matchMathCall("exp", matchValue(1))));
}
auto matchLog2Euler() {
- return expr(anyOf(matchFloatValueNear(llvm::numbers::log2e, false),
+ return expr(anyOf(matchFloatLiteralNear(llvm::numbers::log2e),
matchMathCall("log2", matchEuler())));
}
auto matchLog10Euler() {
- return expr(anyOf(matchFloatValueNear(llvm::numbers::log10e, false),
+ return expr(anyOf(matchFloatLiteralNear(llvm::numbers::log10e),
matchMathCall("log10", matchEuler())));
}
auto matchPi() { return matchFloatValueNear(llvm::numbers::pi); }
-auto matchPiTopLevel() { return matchFloatValueNear(llvm::numbers::pi, false); }
+auto matchPiTopLevel() { return matchFloatLiteralNear(llvm::numbers::pi); }
-auto matchEgamma() { return matchFloatValueNear(llvm::numbers::egamma, false); }
+auto matchEgamma() { return matchFloatLiteralNear(llvm::numbers::egamma); }
auto matchInvPi() {
- return expr(anyOf(matchFloatValueNear(llvm::numbers::inv_pi, false),
+ return expr(anyOf(matchFloatLiteralNear(llvm::numbers::inv_pi),
match1Div(matchPi())));
}
auto matchInvSqrtPi() {
- return expr(anyOf(matchFloatValueNear(llvm::numbers::inv_sqrtpi, false),
+ return expr(anyOf(matchFloatLiteralNear(llvm::numbers::inv_sqrtpi),
match1Div(matchSqrt(matchPi()))));
}
auto matchLn2() {
- return expr(anyOf(matchFloatValueNear(llvm::numbers::ln2, false),
+ return expr(anyOf(matchFloatLiteralNear(llvm::numbers::ln2),
matchMathCall("log", ignoringImplicit(matchValue(2)))));
}
auto machterLn10() {
- return expr(anyOf(matchFloatValueNear(llvm::numbers::ln10, false),
+ return expr(anyOf(matchFloatLiteralNear(llvm::numbers::ln10),
matchMathCall("log", ignoringImplicit(matchValue(10)))));
}
auto matchSqrt2() {
- return expr(anyOf(matchFloatValueNear(llvm::numbers::sqrt2, false),
+ return expr(anyOf(matchFloatLiteralNear(llvm::numbers::sqrt2),
matchSqrt(matchValue(2))));
}
auto matchSqrt3() {
- return expr(anyOf(matchFloatValueNear(llvm::numbers::sqrt3, false),
+ return expr(anyOf(matchFloatLiteralNear(llvm::numbers::sqrt3),
matchSqrt(matchValue(3))));
}
auto matchInvSqrt3() {
- return expr(anyOf(matchFloatValueNear(llvm::numbers::inv_sqrt3, false),
+ return expr(anyOf(matchFloatLiteralNear(llvm::numbers::inv_sqrt3),
match1Div(matchSqrt(matchValue(3)))));
}
@@ -174,8 +169,7 @@ auto matchPhi() {
hasOperatorName("+"), hasEitherOperand(matchValue(1)),
hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
hasRHS(matchValue(2)));
- return expr(
- anyOf(PhiFormula, matchFloatValueNear(llvm::numbers::phi, false)));
+ return expr(anyOf(PhiFormula, matchFloatLiteralNear(llvm::numbers::phi)));
}
EditGenerator
>From e26977801b541e0379f109c112a9451672e79f28 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 27 Oct 2023 23:09:01 +0200
Subject: [PATCH 15/44] add test of using math marco on its own
---
.../test/clang-tidy/checkers/modernize/use-std-numbers.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 8fce42b901b1a..2ceec289ce7c1 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -82,6 +82,10 @@ void foo(){
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2_v<float>;
+ sink(MY_PI);
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: sink(std::numbers::pi);
+
constexpr static auto One = 1;
constexpr static auto Two = 2;
>From b6e3497c3170f36daca89f8ca554149d938f4bbe Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 27 Oct 2023 23:28:30 +0200
Subject: [PATCH 16/44] add newline after code-block directive to maybe fix
docs ci
---
.../docs/clang-tidy/checks/modernize/use-std-numbers.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
index 5da01bd34eaf6..8cd3149879282 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -9,6 +9,7 @@ Does not match the use of variables with that value, and instead,
offers a replacement at the definition of those variables.
.. code-block:: c++
+
double sqrt(double);
double log(double);
void sink(auto&&) {}
>From 53eb3c7a4409d228fb2cace6a8cb7039706fdb61 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 28 Oct 2023 01:45:11 +0200
Subject: [PATCH 17/44] fix APFloat issue
---
clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 98beab00a0181..257ede0897d71 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -39,7 +39,7 @@ using llvm::StringRef;
constexpr auto DiffThreshold = 0.001;
AST_MATCHER_P(clang::FloatingLiteral, near, double, Value) {
- return std::abs(Node.getValue().convertToDouble() - Value) < DiffThreshold;
+ return std::abs(Node.getValueAsApproximateDouble() - Value) < DiffThreshold;
}
AST_MATCHER_P(clang::QualType, hasCanonicalTypeUnqualified,
>From dc26f3e59294e3f331231a3d281b5f0ce64370de Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 28 Oct 2023 01:45:19 +0200
Subject: [PATCH 18/44] run clang-include-cleaner
---
.../clang-tidy/modernize/UseStdNumbersCheck.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 257ede0897d71..5483e01a43dcb 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -7,20 +7,27 @@
//===----------------------------------------------------------------------===//
#include "UseStdNumbersCheck.h"
+#include "../ClangTidyDiagnosticConsumer.h"
+#include "../utils/TransformerClangTidyCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Tooling/Transformer/RewriteRule.h"
#include "clang/Tooling/Transformer/Stencil.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MathExtras.h"
#include <cstdint>
+#include <cstdlib>
#include <string>
+#include <utility>
namespace {
using namespace clang::ast_matchers;
>From 7a66de0a0e7dd95cd5a7bdcaf376866ebae41d93 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 28 Oct 2023 11:20:48 +0200
Subject: [PATCH 19/44] rename chainedIfBound to applyRuleForBoundOrDefault
---
.../clang-tidy/modernize/UseStdNumbersCheck.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 5483e01a43dcb..81098e20ad85b 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -179,9 +179,9 @@ auto matchPhi() {
return expr(anyOf(PhiFormula, matchFloatLiteralNear(llvm::numbers::phi)));
}
-EditGenerator
-chainedIfBound(ASTEdit DefaultEdit,
- llvm::SmallVector<std::pair<StringRef, ASTEdit>, 2> Edits) {
+EditGenerator applyRuleForBoundOrDefault(
+ ASTEdit DefaultEdit,
+ llvm::SmallVector<std::pair<StringRef, ASTEdit>, 2> Edits) {
return [Edits = std::move(Edits), DefaultEdit = std::move(DefaultEdit)](
const MatchFinder::MatchResult &Result) {
auto &Map = Result.Nodes.getMap();
@@ -204,7 +204,7 @@ RewriteRuleWith<std::string> makeRule(const Matcher<clang::Stmt> Matcher,
const auto LongDoubleEdit =
changeTo(cat("std::numbers::", Constant, "_v<long double>"));
- const auto EditRules = chainedIfBound(
+ const auto EditRules = applyRuleForBoundOrDefault(
DefaultEdit, {{"float", FloatEdit}, {"long double", LongDoubleEdit}});
return makeRule(
>From ec2056778f6de3e9241ac1c29a0170577d525d94 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 3 Nov 2023 03:02:30 +0100
Subject: [PATCH 20/44] add support for combinations of casts
---
.../modernize/UseStdNumbersCheck.cpp | 44 ++++++++++++-----
.../checkers/modernize/use-std-numbers.cpp | 48 +++++++++++++++++++
2 files changed, 81 insertions(+), 11 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 81098e20ad85b..84750bd98ef50 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -55,10 +55,27 @@ AST_MATCHER_P(clang::QualType, hasCanonicalTypeUnqualified,
Builder);
}
+AST_MATCHER(clang::QualType, isArithmetic) { return Node->isArithmeticType(); }
+AST_MATCHER(clang::QualType, isFloating) { return Node->isFloatingType(); }
+
+auto ignoreImplicitAndArithmeticCasting(const Matcher<clang::Expr> Matcher) {
+ return expr(
+ ignoringImplicit(expr(hasType(qualType(isArithmetic())),
+ ignoringParenCasts(ignoringImplicit(Matcher)))));
+}
+
+auto ignoreImplicitAndFloatingCasting(const Matcher<clang::Expr> Matcher) {
+ return expr(
+ ignoringImplicit(expr(hasType(qualType(isFloating())),
+ ignoringParenCasts(ignoringImplicit(Matcher)))));
+}
+
auto matchMathCall(const StringRef FunctionName,
const Matcher<clang::Expr> ArgumentMatcher) {
- return callExpr(callee(functionDecl(hasName(FunctionName))),
- hasArgument(0, ignoringImplicit(ArgumentMatcher)));
+ return callExpr(
+ callee(functionDecl(hasName(FunctionName),
+ hasParameter(0, hasType(isArithmetic())))),
+ hasArgument(0, ArgumentMatcher));
}
auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
@@ -73,7 +90,7 @@ auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
//
// We only care about the literal if the match is for a top-level match
auto matchFloatLiteralNear(const double Val) {
- return expr(ignoringImplicit(floatLiteral(near(Val))));
+ return expr(ignoreImplicitAndFloatingCasting(floatLiteral(near(Val))));
}
// Used for non-top-level matchers (i.e. matchers that are used as inner
@@ -91,18 +108,22 @@ auto matchFloatValueNear(const double Val) {
const auto Float = floatLiteral(near(Val));
const auto Dref = declRefExpr(to(varDecl(
- anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))),
+ anyOf(isConstexpr(),
+ varDecl(hasType(qualType(isConstQualified(), isArithmetic())))),
hasInitializer(Float))));
- return expr(ignoringImplicit(anyOf(Float, Dref)));
+ return expr(ignoreImplicitAndFloatingCasting(anyOf(Float, Dref)));
}
auto matchValue(const int64_t ValInt) {
- const auto Int = integerLiteral(equals(ValInt));
- const auto Float = matchFloatValueNear(static_cast<double>(ValInt));
+ const auto Int =
+ expr(ignoreImplicitAndArithmeticCasting(integerLiteral(equals(ValInt))));
+ const auto Float = expr(ignoreImplicitAndFloatingCasting(
+ matchFloatValueNear(static_cast<double>(ValInt))));
const auto Dref = declRefExpr(to(varDecl(
- anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))),
- hasInitializer(expr(ignoringImplicit(anyOf(Int, Float)))))));
- return expr(ignoringImplicit(anyOf(Int, Float, Dref)));
+ anyOf(isConstexpr(),
+ varDecl(hasType(qualType(isConstQualified(), isArithmetic())))),
+ hasInitializer(anyOf(Int, Float)))));
+ return expr(anyOf(Int, Float, Dref));
}
auto match1Div(const Matcher<clang::Expr> Match) {
@@ -208,7 +229,8 @@ RewriteRuleWith<std::string> makeRule(const Matcher<clang::Stmt> Matcher,
DefaultEdit, {{"float", FloatEdit}, {"long double", LongDoubleEdit}});
return makeRule(
- expr(Matcher, unless(isInTemplateInstantiation()),
+ expr(ignoreImplicitAndFloatingCasting(Matcher),
+ unless(isInTemplateInstantiation()),
hasType(qualType(hasCanonicalType(hasCanonicalTypeUnqualified(anyOf(
qualType(asString("float")).bind("float"),
qualType(asString("double")),
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 2ceec289ce7c1..263106b5c4ee5 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -21,6 +21,8 @@ double log10(double Arg);
template<typename T>
void sink(T&&) { }
+void floatSink(float) {}
+
#define MY_PI 3.1415926
#define INV_SQRT3 1 / bar::sqrt(3)
@@ -139,6 +141,52 @@ void foo(){
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: auto log2e = std::numbers::log2e;
+ floatSink(log2(Euler));
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+ floatSink(static_cast<float>(log2(Euler)));
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+ floatSink(1.4426950);
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+ floatSink(static_cast<float>(1.4426950));
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+ floatSink(log2(static_cast<float>(Euler)));
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+ floatSink(static_cast<float>(log2(static_cast<float>(Euler))));
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+ floatSink(static_cast<float>(log2(static_cast<int>(Euler))));
+
+ floatSink(static_cast<int>(log2(static_cast<float>(Euler))));
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e));
+
+ floatSink(1.4426950F);
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+ floatSink(static_cast<double>(1.4426950F));
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+
+ floatSink(static_cast<int>(1.4426950F));
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
+
log10(exp(1));
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer std::numbers math constant [modernize-use-std-numbers]
>From 019f84fd5c9beb370a26ddb65454c2e6a9cf9074 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 4 Nov 2023 00:30:21 +0100
Subject: [PATCH 21/44] check QualType::isNull in custom matchers
---
.../clang-tidy/modernize/UseStdNumbersCheck.cpp | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 84750bd98ef50..d981bb4c31123 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -51,12 +51,17 @@ AST_MATCHER_P(clang::FloatingLiteral, near, double, Value) {
AST_MATCHER_P(clang::QualType, hasCanonicalTypeUnqualified,
Matcher<clang::QualType>, InnerMatcher) {
- return InnerMatcher.matches(Node->getCanonicalTypeUnqualified(), Finder,
+ return !Node.isNull() &&
+ InnerMatcher.matches(Node->getCanonicalTypeUnqualified(), Finder,
Builder);
}
-AST_MATCHER(clang::QualType, isArithmetic) { return Node->isArithmeticType(); }
-AST_MATCHER(clang::QualType, isFloating) { return Node->isFloatingType(); }
+AST_MATCHER(clang::QualType, isArithmetic) {
+ return !Node.isNull() && Node->isArithmeticType();
+}
+AST_MATCHER(clang::QualType, isFloating) {
+ return !Node.isNull() && Node->isFloatingType();
+}
auto ignoreImplicitAndArithmeticCasting(const Matcher<clang::Expr> Matcher) {
return expr(
>From 353f330896572eecdfa96e299b17ea4c7cf276f2 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 4 Nov 2023 01:05:14 +0100
Subject: [PATCH 22/44] refactor Dref match in matchFloatValueNear
- constexpr implies const
- constrain the varDecl's type to be a floating type
- use ignoreImplicitAndFloatingCasting on the hasInitializer expression
---
.../modernize/UseStdNumbersCheck.cpp | 7 ++---
.../checkers/modernize/use-std-numbers.cpp | 28 +++++++++++++++++--
2 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index d981bb4c31123..2a15beb3a1ba9 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -112,10 +112,9 @@ auto matchFloatLiteralNear(const double Val) {
auto matchFloatValueNear(const double Val) {
const auto Float = floatLiteral(near(Val));
- const auto Dref = declRefExpr(to(varDecl(
- anyOf(isConstexpr(),
- varDecl(hasType(qualType(isConstQualified(), isArithmetic())))),
- hasInitializer(Float))));
+ const auto Dref = declRefExpr(
+ to(varDecl(hasType(qualType(isConstQualified(), isFloating())),
+ hasInitializer(ignoreImplicitAndFloatingCasting(Float)))));
return expr(ignoreImplicitAndFloatingCasting(anyOf(Float, Dref)));
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 263106b5c4ee5..bac63edc30f21 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -15,7 +15,12 @@ namespace bar {
double exp(double Arg);
double log(double Arg);
+
double log2(double Arg);
+float log2(float Arg);
+template <typename T>
+auto log2(T val) { return log2(static_cast<double>(val)); }
+
double log10(double Arg);
template<typename T>
@@ -27,6 +32,9 @@ void floatSink(float) {}
#define INV_SQRT3 1 / bar::sqrt(3)
+using my_double = double;
+using my_float = float;
+
void foo(){
static constexpr double Pi = 3.1415926;
// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
@@ -74,11 +82,18 @@ void foo(){
// CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
+ static constexpr my_double Euler5 = 2.7182818;
+ // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr my_double Euler5 = std::numbers::e;
+
+ static constexpr my_float Euler6 = 2.7182818;
+ // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr my_float Euler6 = std::numbers::e_v<float>;
+
static constexpr double InvPi = 1.0 / Pi;
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double InvPi = std::numbers::inv_pi;
- using my_float = const float;
static constexpr my_float Actually2MyFloat = 2;
bar::sqrt(Actually2MyFloat);
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
@@ -137,6 +152,14 @@ void foo(){
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
+ log2(Euler5);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::log2e;
+
+ log2(Euler6);
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: std::numbers::log2e_v<float>;
+
auto log2e = 1.4426950;
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: auto log2e = std::numbers::log2e;
@@ -172,7 +195,7 @@ void foo(){
floatSink(static_cast<int>(log2(static_cast<float>(Euler))));
// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer std::numbers math constant [modernize-use-std-numbers]
- // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e));
+ // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
floatSink(1.4426950F);
// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
@@ -303,7 +326,6 @@ void baz(){
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr T Phi3 = std::numbers::phi_v<long double>;
- using my_float = const float;
static constexpr my_float Actually2MyFloat = 2;
bar::sqrt(Actually2MyFloat);
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
>From 70eb8e8d89ec8ee5bbcbfb74f3824a395ee01b1d Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 4 Nov 2023 01:11:31 +0100
Subject: [PATCH 23/44] change Dref match in MatchValue
- constexpr implies const
---
.../clang-tidy/modernize/UseStdNumbersCheck.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 2a15beb3a1ba9..ee4c530a62963 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -123,10 +123,9 @@ auto matchValue(const int64_t ValInt) {
expr(ignoreImplicitAndArithmeticCasting(integerLiteral(equals(ValInt))));
const auto Float = expr(ignoreImplicitAndFloatingCasting(
matchFloatValueNear(static_cast<double>(ValInt))));
- const auto Dref = declRefExpr(to(varDecl(
- anyOf(isConstexpr(),
- varDecl(hasType(qualType(isConstQualified(), isArithmetic())))),
- hasInitializer(anyOf(Int, Float)))));
+ const auto Dref = declRefExpr(
+ to(varDecl(hasType(qualType(isConstQualified(), isArithmetic())),
+ hasInitializer(anyOf(Int, Float)))));
return expr(anyOf(Int, Float, Dref));
}
>From 42cad98a437a9253f481da3af07f342871af1147 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 4 Nov 2023 01:14:41 +0100
Subject: [PATCH 24/44] fix implicit casts in hasInitializer of matchValue
- implicit conversiosn might occur
- allow only implicit casts to floating types
when the initializer is a float literal
- allow implicit conversions for ints
---
.../clang-tidy/modernize/UseStdNumbersCheck.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index ee4c530a62963..f956bd5ae153e 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -123,9 +123,10 @@ auto matchValue(const int64_t ValInt) {
expr(ignoreImplicitAndArithmeticCasting(integerLiteral(equals(ValInt))));
const auto Float = expr(ignoreImplicitAndFloatingCasting(
matchFloatValueNear(static_cast<double>(ValInt))));
- const auto Dref = declRefExpr(
- to(varDecl(hasType(qualType(isConstQualified(), isArithmetic())),
- hasInitializer(anyOf(Int, Float)))));
+ const auto Dref = declRefExpr(to(varDecl(
+ hasType(qualType(isConstQualified(), isArithmetic())),
+ hasInitializer(expr(anyOf(ignoringImplicit(Int),
+ ignoreImplicitAndFloatingCasting(Float)))))));
return expr(anyOf(Int, Float, Dref));
}
>From 71fc18226433119a178d8f4a18f6cc794234ab5e Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 4 Nov 2023 01:18:58 +0100
Subject: [PATCH 25/44] add test for int constants initialized with float
---
.../test/clang-tidy/checkers/modernize/use-std-numbers.cpp | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index bac63edc30f21..eca908decbbb2 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -90,6 +90,10 @@ void foo(){
// CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr my_float Euler6 = std::numbers::e_v<float>;
+ static constexpr int NotEuler7 = 2.7182818;
+ // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: static constexpr int NotEuler7 = std::numbers::e;
+
static constexpr double InvPi = 1.0 / Pi;
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double InvPi = std::numbers::inv_pi;
@@ -160,6 +164,8 @@ void foo(){
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e_v<float>;
+ log2(NotEuler7);
+
auto log2e = 1.4426950;
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer std::numbers math constant [modernize-use-std-numbers]
// CHECK-FIXES: auto log2e = std::numbers::log2e;
>From 2fe0d0d67fcac68244a2bed865f7c0071158e2a8 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 4 Nov 2023 01:28:05 +0100
Subject: [PATCH 26/44] extend documentation
- provide the list of supported constants
- explain replacements a bit more
---
.../checks/modernize/use-std-numbers.rst | 32 ++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
index 8cd3149879282..e51da6575958b 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -4,15 +4,44 @@ modernize-use-std-numbers
=========================
Finds constants and function calls to math functions that can be replaced
-with c++20's mathematical constants from the ``numbers`` header and offers fix-it hints.
+with c++20's mathematical constants from the ``numbers`` header and offers
+fix-it hints.
Does not match the use of variables with that value, and instead,
offers a replacement at the definition of those variables.
+Function calls that match the pattern of how the constant is calculated are
+matched and replaced with the ``std::numbers`` constant.
+The use of macros gets replaced with the corresponding ``std::numbers``
+constant, instead of changing the macro definition.
+
+The following list of constants from the ``numbers`` header are supported:
+
+* e
+* log2e
+* log10e
+* pi
+* inv_pi
+* inv_sqrtpi
+* ln2
+* ln10
+* sqrt2
+* sqrt3
+* inv_sqrt3
+* egamma
+* phi
+
+The list currently includes all constants as of C++20.
+
+The replacements try to match the type of the inserted constant by how the
+removed expression was used, e.g., switching between ``std::numbers::e`` to
+``std::numbers::e_v<float>`` or ``std::numbers::e_v<long double>``
+where appropriate.
.. code-block:: c++
double sqrt(double);
double log(double);
void sink(auto&&) {}
+ void floatSink(float);
#define MY_PI 3.1415926
@@ -25,4 +54,5 @@ offers a replacement at the definition of those variables.
log2(Euler); // std::numbers::log2e;
1 / sqrt(MY_PI); // std::numbers::inv_sqrtpi;
sink(MY_PI); // sink(std::numbers::pi);
+ floatSink(MY_PI); // floatSink(std::numbers::pi_v<float>);
}
>From fd888ae7914c49ad6b3539232c9be9afc27f23db Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 10 Nov 2023 17:52:41 +0100
Subject: [PATCH 27/44] refactor from using transformer to a normal check
- change from seperated matchers to a single unified matcher
- prefer to diagnose patterns (formulas) before literals,
diagnosing the expr with the largest possible impact/fixit
- the numbers constant that is the closest match to the matched literal
is offered as a replacement, instead of the first one found.
- explicitly mention the constant that the fix-it is offering
---
.../modernize/UseStdNumbersCheck.cpp | 352 ++++++++++++------
.../clang-tidy/modernize/UseStdNumbersCheck.h | 15 +-
.../checkers/modernize/use-std-numbers.cpp | 198 +++++-----
3 files changed, 353 insertions(+), 212 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index f956bd5ae153e..a405947e7f872 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -8,7 +8,6 @@
#include "UseStdNumbersCheck.h"
#include "../ClangTidyDiagnosticConsumer.h"
-#include "../utils/TransformerClangTidyCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
@@ -18,29 +17,28 @@
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/LLVM.h"
-#include "clang/Tooling/Transformer/RewriteRule.h"
-#include "clang/Tooling/Transformer/Stencil.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MathExtras.h"
+#include <array>
#include <cstdint>
#include <cstdlib>
+#include <initializer_list>
#include <string>
+#include <tuple>
#include <utility>
namespace {
using namespace clang::ast_matchers;
using clang::ast_matchers::internal::Matcher;
-using clang::transformer::addInclude;
-using clang::transformer::applyFirst;
-using clang::transformer::ASTEdit;
-using clang::transformer::cat;
-using clang::transformer::changeTo;
-using clang::transformer::edit;
-using clang::transformer::EditGenerator;
-using clang::transformer::flattenVector;
-using clang::transformer::RewriteRuleWith;
using llvm::StringRef;
constexpr auto DiffThreshold = 0.001;
@@ -63,6 +61,19 @@ AST_MATCHER(clang::QualType, isFloating) {
return !Node.isNull() && Node->isFloatingType();
}
+AST_MATCHER_P(clang::Expr, anyOfExhaustive,
+ llvm::ArrayRef<Matcher<clang::Stmt>>, Exprs) {
+ bool FoundMatch = false;
+ for (const auto &InnerMatcher : Exprs) {
+ clang::ast_matchers::internal::BoundNodesTreeBuilder Result = *Builder;
+ if (InnerMatcher.matches(Node, Finder, &Result)) {
+ *Builder = std::move(Result);
+ FoundMatch = true;
+ }
+ }
+ return FoundMatch;
+}
+
auto ignoreImplicitAndArithmeticCasting(const Matcher<clang::Expr> Matcher) {
return expr(
ignoringImplicit(expr(hasType(qualType(isArithmetic())),
@@ -77,10 +88,10 @@ auto ignoreImplicitAndFloatingCasting(const Matcher<clang::Expr> Matcher) {
auto matchMathCall(const StringRef FunctionName,
const Matcher<clang::Expr> ArgumentMatcher) {
- return callExpr(
- callee(functionDecl(hasName(FunctionName),
- hasParameter(0, hasType(isArithmetic())))),
- hasArgument(0, ArgumentMatcher));
+ return expr(ignoreImplicitAndFloatingCasting(
+ callExpr(callee(functionDecl(hasName(FunctionName),
+ hasParameter(0, hasType(isArithmetic())))),
+ hasArgument(0, ArgumentMatcher))));
}
auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
@@ -93,9 +104,10 @@ auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
// E.g. The matcher of `std::numbers::pi` uses this matcher to look to
// floatLiterals that have the value of pi.
//
-// We only care about the literal if the match is for a top-level match
-auto matchFloatLiteralNear(const double Val) {
- return expr(ignoreImplicitAndFloatingCasting(floatLiteral(near(Val))));
+// If the match is for a top-level match, we only care about the literal.
+auto matchFloatLiteralNear(const StringRef Constant, const double Val) {
+ return expr(
+ ignoreImplicitAndFloatingCasting(floatLiteral(near(Val)).bind(Constant)));
}
// Used for non-top-level matchers (i.e. matchers that are used as inner
@@ -140,58 +152,85 @@ auto matchEuler() {
matchMathCall("exp", matchValue(1))));
}
auto matchEulerTopLevel() {
- return expr(anyOf(matchFloatLiteralNear(llvm::numbers::e),
- matchMathCall("exp", matchValue(1))));
+ return expr(anyOf(matchFloatLiteralNear("e_literal", llvm::numbers::e),
+ matchMathCall("exp", matchValue(1)).bind("e_pattern")))
+ .bind("e");
}
auto matchLog2Euler() {
- return expr(anyOf(matchFloatLiteralNear(llvm::numbers::log2e),
- matchMathCall("log2", matchEuler())));
+ return expr(
+ anyOf(matchFloatLiteralNear("log2e_literal", llvm::numbers::log2e),
+ matchMathCall("log2", matchEuler()).bind("log2e_pattern")))
+ .bind("log2e");
}
auto matchLog10Euler() {
- return expr(anyOf(matchFloatLiteralNear(llvm::numbers::log10e),
- matchMathCall("log10", matchEuler())));
+ return expr(
+ anyOf(
+ matchFloatLiteralNear("log10e_literal", llvm::numbers::log10e),
+ matchMathCall("log10", matchEuler()).bind("log10e_pattern")))
+ .bind("log10e");
}
auto matchPi() { return matchFloatValueNear(llvm::numbers::pi); }
-auto matchPiTopLevel() { return matchFloatLiteralNear(llvm::numbers::pi); }
+auto matchPiTopLevel() {
+ return matchFloatLiteralNear("pi_literal", llvm::numbers::pi).bind("pi");
+}
-auto matchEgamma() { return matchFloatLiteralNear(llvm::numbers::egamma); }
+auto matchEgamma() {
+ return matchFloatLiteralNear("egamma_literal", llvm::numbers::egamma)
+ .bind("egamma");
+}
auto matchInvPi() {
- return expr(anyOf(matchFloatLiteralNear(llvm::numbers::inv_pi),
- match1Div(matchPi())));
+ return expr(anyOf(matchFloatLiteralNear("inv_pi_literal",
+ llvm::numbers::inv_pi),
+ match1Div(matchPi()).bind("inv_pi_pattern")))
+ .bind("inv_pi");
}
auto matchInvSqrtPi() {
- return expr(anyOf(matchFloatLiteralNear(llvm::numbers::inv_sqrtpi),
- match1Div(matchSqrt(matchPi()))));
+ return expr(anyOf(matchFloatLiteralNear("inv_sqrtpi_literal",
+ llvm::numbers::inv_sqrtpi),
+ match1Div(matchSqrt(matchPi())).bind("inv_sqrtpi_pattern")))
+ .bind("inv_sqrtpi");
}
auto matchLn2() {
- return expr(anyOf(matchFloatLiteralNear(llvm::numbers::ln2),
- matchMathCall("log", ignoringImplicit(matchValue(2)))));
+ return expr(anyOf(matchFloatLiteralNear("ln2_literal", llvm::numbers::ln2),
+ matchMathCall("log", ignoringImplicit(matchValue(2)))
+ .bind("ln2_pattern")))
+ .bind("ln2");
}
auto machterLn10() {
- return expr(anyOf(matchFloatLiteralNear(llvm::numbers::ln10),
- matchMathCall("log", ignoringImplicit(matchValue(10)))));
+ return expr(anyOf(matchFloatLiteralNear("ln10_literal", llvm::numbers::ln10),
+ matchMathCall("log", ignoringImplicit(matchValue(10)))
+ .bind("ln10_pattern")))
+ .bind("ln10");
}
auto matchSqrt2() {
- return expr(anyOf(matchFloatLiteralNear(llvm::numbers::sqrt2),
- matchSqrt(matchValue(2))));
+ return expr(
+ anyOf(matchFloatLiteralNear("sqrt2_literal", llvm::numbers::sqrt2),
+ matchSqrt(matchValue(2)).bind("sqrt2_pattern")))
+ .bind("sqrt2");
}
auto matchSqrt3() {
- return expr(anyOf(matchFloatLiteralNear(llvm::numbers::sqrt3),
- matchSqrt(matchValue(3))));
+ return expr(
+ anyOf(matchFloatLiteralNear("sqrt3_literal", llvm::numbers::sqrt3),
+ matchSqrt(matchValue(3)).bind("sqrt3_pattern")))
+ .bind("sqrt3");
}
auto matchInvSqrt3() {
- return expr(anyOf(matchFloatLiteralNear(llvm::numbers::inv_sqrt3),
- match1Div(matchSqrt(matchValue(3)))));
+ return expr(
+ anyOf(
+ matchFloatLiteralNear("inv_sqrt3_literal",
+ llvm::numbers::inv_sqrt3),
+ match1Div(matchSqrt(matchValue(3))).bind("inv_sqrt3_pattern")))
+ .bind("inv_sqrt3");
}
auto matchPhi() {
@@ -201,88 +240,179 @@ auto matchPhi() {
hasOperatorName("+"), hasEitherOperand(matchValue(1)),
hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
hasRHS(matchValue(2)));
- return expr(anyOf(PhiFormula, matchFloatLiteralNear(llvm::numbers::phi)));
-}
-
-EditGenerator applyRuleForBoundOrDefault(
- ASTEdit DefaultEdit,
- llvm::SmallVector<std::pair<StringRef, ASTEdit>, 2> Edits) {
- return [Edits = std::move(Edits), DefaultEdit = std::move(DefaultEdit)](
- const MatchFinder::MatchResult &Result) {
- auto &Map = Result.Nodes.getMap();
- for (const auto &[Id, EditOfId] : Edits) {
- if (Map.find(Id) != Map.end()) {
- return edit(EditOfId)(Result);
- }
- }
- return edit(DefaultEdit)(Result);
- };
+ return expr(anyOf(PhiFormula.bind("phi_pattern"),
+ matchFloatLiteralNear("phi_literal", llvm::numbers::phi)))
+ .bind("phi");
}
-RewriteRuleWith<std::string> makeRule(const Matcher<clang::Stmt> Matcher,
- const StringRef Constant) {
- static const auto AddNumbersInclude =
- addInclude("numbers", clang::transformer::IncludeFormat::Angled);
+std::string getCode(const StringRef Constant, const bool IsFloat,
+ const bool IsLongDouble) {
+ if (IsFloat) {
+ return ("std::numbers::" + Constant + "_v<float>").str();
+ }
+ if (IsLongDouble) {
+ return ("std::numbers::" + Constant + "_v<long double>").str();
+ }
+ return ("std::numbers::" + Constant).str();
+}
- const auto DefaultEdit = changeTo(cat("std::numbers::", Constant));
- const auto FloatEdit = changeTo(cat("std::numbers::", Constant, "_v<float>"));
- const auto LongDoubleEdit =
- changeTo(cat("std::numbers::", Constant, "_v<long double>"));
+bool isRangeOfCompleteMacro(const clang::SourceRange &Range,
+ const clang::SourceManager &SM,
+ const clang::LangOptions &LO) {
+ if (!Range.getBegin().isMacroID()) {
+ return false;
+ }
+ if (!clang::Lexer::isAtStartOfMacroExpansion(Range.getBegin(), SM, LO)) {
+ return false;
+ }
+
+ if (!Range.getEnd().isMacroID()) {
+ return false;
+ }
+
+ if (!clang::Lexer::isAtEndOfMacroExpansion(Range.getEnd(), SM, LO)) {
+ return false;
+ }
+
+ return true;
+}
- const auto EditRules = applyRuleForBoundOrDefault(
- DefaultEdit, {{"float", FloatEdit}, {"long double", LongDoubleEdit}});
+} // namespace
- return makeRule(
- expr(ignoreImplicitAndFloatingCasting(Matcher),
+namespace clang::tidy::modernize {
+UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name,
+ ClangTidyContext *const Context)
+ : ClangTidyCheck(Name, Context),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()) {}
+
+void UseStdNumbersCheck::registerMatchers(MatchFinder *Finder) {
+ static const auto ConstantMatchers = {
+ matchLog2Euler(), matchLog10Euler(), matchEulerTopLevel(), matchEgamma(),
+ matchInvSqrtPi(), matchInvPi(), matchPiTopLevel(), matchLn2(),
+ machterLn10(), matchSqrt2(), matchInvSqrt3(), matchSqrt3(),
+ matchPhi(),
+ };
+
+ Finder->addMatcher(
+ expr(anyOfExhaustive(ConstantMatchers),
unless(isInTemplateInstantiation()),
+ unless(hasParent(expr(
+ anyOf(implicitCastExpr(hasImplicitDestinationType(isFloating())),
+ explicitCastExpr(hasDestinationType(isFloating())))))),
hasType(qualType(hasCanonicalType(hasCanonicalTypeUnqualified(anyOf(
qualType(asString("float")).bind("float"),
qualType(asString("double")),
qualType(asString("long double")).bind("long double"))))))),
- flattenVector({edit(AddNumbersInclude), EditRules}),
- cat("prefer std::numbers math constant"));
-}
-
-/*
- List of all math constants
- + e
- + log2e
- + log10e
- + pi
- + inv_pi
- + inv_sqrtpi
- + ln2
- + ln10
- + sqrt2
- + sqrt3
- + inv_sqrt3
- + egamma
- + phi
-*/
-
-RewriteRuleWith<std::string> makeRewriteRule() {
- return applyFirst({
- makeRule(matchLog2Euler(), "log2e"),
- makeRule(matchLog10Euler(), "log10e"),
- makeRule(matchEulerTopLevel(), "e"),
- makeRule(matchEgamma(), "egamma"),
- makeRule(matchInvSqrtPi(), "inv_sqrtpi"),
- makeRule(matchInvPi(), "inv_pi"),
- makeRule(matchPiTopLevel(), "pi"),
- makeRule(matchLn2(), "ln2"),
- makeRule(machterLn10(), "ln10"),
- makeRule(matchSqrt2(), "sqrt2"),
- makeRule(matchInvSqrt3(), "inv_sqrt3"),
- makeRule(matchSqrt3(), "sqrt3"),
- makeRule(matchPhi(), "phi"),
+ this);
+}
+
+void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
+ /*
+ List of all math constants in the `<numbers>` header
+ + e
+ + log2e
+ + log10e
+ + pi
+ + inv_pi
+ + inv_sqrtpi
+ + ln2
+ + ln10
+ + sqrt2
+ + sqrt3
+ + inv_sqrt3
+ + egamma
+ + phi
+ */
+
+ // The ordering determines what constants are looked at first.
+ // E.g. look at 'inv_sqrt3' before 'sqrt3' to be able to replace the larger
+ // expression
+ constexpr auto Constants = std::array<std::pair<StringRef, double>, 13>{
+ std::pair{StringRef{"log2e"}, llvm::numbers::log2e},
+ std::pair{StringRef{"log10e"}, llvm::numbers::log10e},
+ std::pair{StringRef{"e"}, llvm::numbers::e},
+ std::pair{StringRef{"egamma"}, llvm::numbers::egamma},
+ std::pair{StringRef{"inv_sqrtpi"}, llvm::numbers::inv_sqrtpi},
+ std::pair{StringRef{"inv_pi"}, llvm::numbers::inv_pi},
+ std::pair{StringRef{"pi"}, llvm::numbers::pi},
+ std::pair{StringRef{"ln2"}, llvm::numbers::ln2},
+ std::pair{StringRef{"ln10"}, llvm::numbers::ln10},
+ std::pair{StringRef{"sqrt2"}, llvm::numbers::sqrt2},
+ std::pair{StringRef{"inv_sqrt3"}, llvm::numbers::inv_sqrt3},
+ std::pair{StringRef{"sqrt3"}, llvm::numbers::sqrt3},
+ std::pair{StringRef{"phi"}, llvm::numbers::phi},
+ };
+
+ auto MatchedLiterals =
+ llvm::SmallVector<std::tuple<std::string, double, const Expr *>>{};
+
+ const auto &SM = *Result.SourceManager;
+ const auto &LO = Result.Context->getLangOpts();
+
+ const auto IsFloat = Result.Nodes.getNodeAs<QualType>("float") != nullptr;
+ const auto IsLongDouble =
+ Result.Nodes.getNodeAs<QualType>("long double") != nullptr;
+
+ for (const auto &[ConstantName, ConstantValue] : Constants) {
+ const auto *const Match = Result.Nodes.getNodeAs<Expr>(ConstantName);
+ if (Match == nullptr) {
+ continue;
+ }
+
+ const auto Range = Match->getSourceRange();
+
+ if (Range.getBegin().isMacroID() &&
+ !isRangeOfCompleteMacro(Range, SM, LO)) {
+ continue;
+ }
+
+ const auto PatternBindString = (ConstantName + "_pattern").str();
+ if (Result.Nodes.getNodeAs<Expr>(PatternBindString) != nullptr) {
+ const auto Code = getCode(ConstantName, IsFloat, IsLongDouble);
+ diag(Range.getBegin(), "prefer '%0' math constant")
+ << Code << FixItHint::CreateReplacement(Range, Code);
+ return;
+ }
+
+ const auto LiteralBindString = (ConstantName + "_literal").str();
+ if (const auto *const Literal =
+ Result.Nodes.getNodeAs<FloatingLiteral>(LiteralBindString)) {
+ MatchedLiterals.emplace_back(
+ ConstantName,
+ std::abs(Literal->getValueAsApproximateDouble() - ConstantValue),
+ Match);
+ }
+ }
+
+ // We may have had no matches with literals, but a match with a pattern that
+ // was a subexpression of a macro which was therefore skipped.
+ if (MatchedLiterals.empty()) {
+ return;
+ }
+
+ llvm::sort(MatchedLiterals, [](const auto &LHS, const auto &RHS) {
+ return std::get<1>(LHS) < std::get<1>(RHS);
});
+
+ const auto &[Constant, _, Node] = MatchedLiterals.front();
+
+ const auto Range = Node->getSourceRange();
+ if (Range.getBegin().isMacroID() && !isRangeOfCompleteMacro(Range, SM, LO)) {
+ return;
+ }
+
+ const auto Code = getCode(Constant, IsFloat, IsLongDouble);
+ diag(Range.getBegin(), "prefer '%0' math constant")
+ << Code << FixItHint::CreateReplacement(Range, Code)
+ << IncludeInserter.createIncludeInsertion(
+ Result.SourceManager->getFileID(Range.getBegin()), "<numbers>");
}
-} // namespace
-namespace clang::tidy::modernize {
-UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name,
- ClangTidyContext *const Context)
- : TransformerClangTidyCheck(Name, Context) {
- setRule(makeRewriteRule());
+void UseStdNumbersCheck::registerPPCallbacks(const SourceManager &SM,
+ Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) {
+ IncludeInserter.registerPreprocessor(PP);
}
} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
index 3cf2d9244cc81..da52f2b9ab4ce 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
@@ -9,7 +9,8 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDNUMBERSCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDNUMBERSCHECK_H
-#include "../utils/TransformerClangTidyCheck.h"
+#include "../ClangTidyCheck.h"
+#include "../utils/IncludeInserter.h"
namespace clang::tidy::modernize {
@@ -21,13 +22,23 @@ namespace clang::tidy::modernize {
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-numbers.html
-class UseStdNumbersCheck : public utils::TransformerClangTidyCheck {
+class UseStdNumbersCheck : public ClangTidyCheck {
public:
UseStdNumbersCheck(StringRef Name, ClangTidyContext *Context);
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return LangOpts.CPlusPlus20;
}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) override;
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override {
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+ }
+
+private:
+ utils::IncludeInserter IncludeInserter;
};
} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index eca908decbbb2..c979d8e06efa2 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -9,7 +9,7 @@ namespace bar {
auto sqrt(T val) { return sqrt(static_cast<double>(val)); }
static constexpr double e = 2.718281828459045235360287471352662497757247093;
- // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double e = std::numbers::e;
}
@@ -37,20 +37,20 @@ using my_float = float;
void foo(){
static constexpr double Pi = 3.1415926;
- // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Pi = std::numbers::pi;
static constexpr double Euler = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Euler = std::numbers::e;
static constexpr double Phi = 1.6180339;
- // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Phi = std::numbers::phi;
static constexpr double PiCopy = Pi;
static constexpr double PiDefineFromMacro = MY_PI;
- // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double PiDefineFromMacro = std::numbers::pi;
// not close enough to match value (DiffThreshold)
@@ -59,67 +59,67 @@ void foo(){
static constexpr double Phi2 = 1.61;
static constexpr double Pi3 = 3.1415926L;
- // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Pi3 = std::numbers::pi;
static constexpr double Euler3 = 2.7182818L;
- // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Euler3 = std::numbers::e;
static constexpr double Phi3 = 1.6180339L;
- // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Phi3 = std::numbers::phi;
static constexpr long double Pi4 = 3.1415926L;
- // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::pi_v<long double>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr long double Pi4 = std::numbers::pi_v<long double>;
static constexpr long double Euler4 = 2.7182818L;
- // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer 'std::numbers::e_v<long double>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr long double Euler4 = std::numbers::e_v<long double>;
static constexpr long double Phi4 = 1.6180339L;
- // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::phi_v<long double>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
static constexpr my_double Euler5 = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr my_double Euler5 = std::numbers::e;
static constexpr my_float Euler6 = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::e_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr my_float Euler6 = std::numbers::e_v<float>;
static constexpr int NotEuler7 = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr int NotEuler7 = std::numbers::e;
static constexpr double InvPi = 1.0 / Pi;
- // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::inv_pi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double InvPi = std::numbers::inv_pi;
static constexpr my_float Actually2MyFloat = 2;
bar::sqrt(Actually2MyFloat);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2_v<float>;
sink(MY_PI);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::pi);
constexpr static auto One = 1;
constexpr static auto Two = 2;
bar::sqrt(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
bar::sqrt(Two);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
bar::sqrt(2.0);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
auto Not2 = 2;
@@ -128,169 +128,169 @@ void foo(){
const auto Actually2 = 2;
bar::sqrt(Actually2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
exp(1);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::e;
exp(One);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::e;
exp(1.00000000000001);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::e;
log2(exp(1));
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
log2(Euler);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
log2(bar::e);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
log2(Euler5);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
log2(Euler6);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e_v<float>;
log2(NotEuler7);
auto log2e = 1.4426950;
- // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: auto log2e = std::numbers::log2e;
floatSink(log2(Euler));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<float>(log2(Euler)));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(1.4426950);
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<float>(1.4426950));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(log2(static_cast<float>(Euler)));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<float>(log2(static_cast<float>(Euler))));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<float>(log2(static_cast<int>(Euler))));
floatSink(static_cast<int>(log2(static_cast<float>(Euler))));
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
floatSink(1.4426950F);
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<double>(1.4426950F));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<int>(1.4426950F));
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
log10(exp(1));
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log10e;
log10(Euler);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log10e;
log10(bar::e);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log10e;
auto log10e = .434294;
- // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: auto log10e = std::numbers::log10e;
auto egamma = 0.5772156 * 42;
- // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::egamma' math constant [modernize-use-std-numbers]
// CHECK-FIXES: auto egamma = std::numbers::egamma * 42;
sink(InvPi);
sink(1 / Pi);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_pi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_pi);
sink(1 / bar::sqrt(Pi));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
sink(1 / bar::sqrt(MY_PI));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
log(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::ln2;
log(10);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::ln10;
bar::sqrt(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
sink(1 / bar::sqrt(3));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrt3);
sink(INV_SQRT3);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrt3);
+ const auto inv_sqrt3f = .577350269F;
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::inv_sqrt3_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: const auto inv_sqrt3f = std::numbers::inv_sqrt3_v<float>;
+
bar::sqrt(3);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt3;
- auto phi = 1.6180339;
- // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers]
- // CHECK-FIXES: auto phi = std::numbers::phi;
+ auto somePhi = 1.6180339;
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+ // CHECK-FIXES: auto somePhi = std::numbers::phi;
sink(Phi);
sink((42 + bar::sqrt(5)) / 2);
sink((1 + bar::sqrt(5)) / 2);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::phi);
sink((bar::sqrt(5.0F) + 1) / 2);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::phi_v<float>);
}
@@ -299,20 +299,20 @@ void foo(){
template <typename T>
void baz(){
static constexpr T Pi = 3.1415926;
- // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr T Pi = std::numbers::pi;
static constexpr T Euler = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr T Euler = std::numbers::e;
static constexpr T Phi = 1.6180339;
- // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr T Phi = std::numbers::phi;
static constexpr T PiCopy = Pi;
static constexpr T PiDefineFromMacro = MY_PI;
- // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr T PiDefineFromMacro = std::numbers::pi;
// not close enough to match value (DiffThreshold)
@@ -321,33 +321,33 @@ void baz(){
static constexpr T Phi2 = 1.61;
static constexpr T Pi3 = 3.1415926L;
- // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::pi_v<long double>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr T Pi3 = std::numbers::pi_v<long double>;
static constexpr T Euler3 = 2.7182818L;
- // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e_v<long double>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr T Euler3 = std::numbers::e_v<long double>;
static constexpr T Phi3 = 1.6180339L;
- // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer 'std::numbers::phi_v<long double>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr T Phi3 = std::numbers::phi_v<long double>;
static constexpr my_float Actually2MyFloat = 2;
bar::sqrt(Actually2MyFloat);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2_v<float>;
constexpr static T One = 1;
constexpr static T Two = 2;
bar::sqrt(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
bar::sqrt(Two);
bar::sqrt(2.0);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
T Not2 = 2;
@@ -358,47 +358,47 @@ void baz(){
bar::sqrt(Actually2);
exp(1);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::e;
exp(One);
exp(1.00000000000001);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::e;
log2(exp(1));
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
log2(Euler);
log2(bar::e);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
T log2e = 1.4426950;
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: T log2e = std::numbers::log2e;
log10(exp(1));
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log10e;
log10(Euler);
log10(bar::e);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log10e;
T log10e = .434294;
- // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
// CHECK-FIXES: T log10e = std::numbers::log10e;
T egamma = 0.5772156 * 42;
- // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::egamma' math constant [modernize-use-std-numbers]
// CHECK-FIXES: T egamma = std::numbers::egamma * 42;
sink(1 / Pi);
@@ -406,44 +406,44 @@ void baz(){
sink(1 / bar::sqrt(Pi));
sink(1 / bar::sqrt(MY_PI));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
log(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::ln2;
log(10);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::ln10;
bar::sqrt(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
sink(1 / bar::sqrt(3));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrt3);
bar::sqrt(3);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt3;
T phi = 1.6180339;
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: T phi = std::numbers::phi;
sink((42 + bar::sqrt(5)) / 2);
sink((1 + bar::sqrt(5)) / 2);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::phi);
sink((bar::sqrt(5.0F) + 1) / 2);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' math constant [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::phi_v<float>);
}
>From 95cee0f9aa4d8fc4fcdca6c3577cb2b1ccc1f5c8 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 10 Nov 2023 22:51:28 +0100
Subject: [PATCH 28/44] change message to include what is being replaced and
how far off literals are
---
.../modernize/UseStdNumbersCheck.cpp | 20 +-
.../checkers/modernize/use-std-numbers.cpp | 188 +++++++++---------
2 files changed, 106 insertions(+), 102 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index a405947e7f872..cb7579d42a33c 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -27,6 +27,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MathExtras.h"
#include <array>
#include <cstdint>
@@ -363,16 +364,16 @@ void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
const auto Range = Match->getSourceRange();
- if (Range.getBegin().isMacroID() &&
- !isRangeOfCompleteMacro(Range, SM, LO)) {
+ const auto IsMacro = Range.getBegin().isMacroID();
+ if (IsMacro && !isRangeOfCompleteMacro(Range, SM, LO)) {
continue;
}
const auto PatternBindString = (ConstantName + "_pattern").str();
if (Result.Nodes.getNodeAs<Expr>(PatternBindString) != nullptr) {
const auto Code = getCode(ConstantName, IsFloat, IsLongDouble);
- diag(Range.getBegin(), "prefer '%0' math constant")
- << Code << FixItHint::CreateReplacement(Range, Code);
+ diag(Range.getBegin(), "prefer '%0' to this %select{formula|macro}1")
+ << Code << IsMacro << FixItHint::CreateReplacement(Range, Code);
return;
}
@@ -396,16 +397,19 @@ void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
return std::get<1>(LHS) < std::get<1>(RHS);
});
- const auto &[Constant, _, Node] = MatchedLiterals.front();
+ const auto &[Constant, Diff, Node] = MatchedLiterals.front();
const auto Range = Node->getSourceRange();
- if (Range.getBegin().isMacroID() && !isRangeOfCompleteMacro(Range, SM, LO)) {
+ const auto IsMacro = Range.getBegin().isMacroID();
+ if (IsMacro && !isRangeOfCompleteMacro(Range, SM, LO)) {
return;
}
const auto Code = getCode(Constant, IsFloat, IsLongDouble);
- diag(Range.getBegin(), "prefer '%0' math constant")
- << Code << FixItHint::CreateReplacement(Range, Code)
+ diag(Range.getBegin(),
+ "prefer '%0' to this %select{literal|macro}1, differs by '%2'")
+ << Code << IsMacro << llvm::formatv("{0:e2}", Diff).str()
+ << FixItHint::CreateReplacement(Range, Code)
<< IncludeInserter.createIncludeInsertion(
Result.SourceManager->getFileID(Range.getBegin()), "<numbers>");
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index c979d8e06efa2..71f01ffaeb8df 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -9,7 +9,7 @@ namespace bar {
auto sqrt(T val) { return sqrt(static_cast<double>(val)); }
static constexpr double e = 2.718281828459045235360287471352662497757247093;
- // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e' to this literal, differs by '0.00e+00' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double e = std::numbers::e;
}
@@ -37,20 +37,20 @@ using my_float = float;
void foo(){
static constexpr double Pi = 3.1415926;
- // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Pi = std::numbers::pi;
static constexpr double Euler = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Euler = std::numbers::e;
static constexpr double Phi = 1.6180339;
- // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Phi = std::numbers::phi;
static constexpr double PiCopy = Pi;
static constexpr double PiDefineFromMacro = MY_PI;
- // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double PiDefineFromMacro = std::numbers::pi;
// not close enough to match value (DiffThreshold)
@@ -59,67 +59,67 @@ void foo(){
static constexpr double Phi2 = 1.61;
static constexpr double Pi3 = 3.1415926L;
- // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Pi3 = std::numbers::pi;
static constexpr double Euler3 = 2.7182818L;
- // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Euler3 = std::numbers::e;
static constexpr double Phi3 = 1.6180339L;
- // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double Phi3 = std::numbers::phi;
static constexpr long double Pi4 = 3.1415926L;
- // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::pi_v<long double>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr long double Pi4 = std::numbers::pi_v<long double>;
static constexpr long double Euler4 = 2.7182818L;
- // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer 'std::numbers::e_v<long double>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer 'std::numbers::e_v<long double>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr long double Euler4 = std::numbers::e_v<long double>;
static constexpr long double Phi4 = 1.6180339L;
- // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::phi_v<long double>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::phi_v<long double>' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
static constexpr my_double Euler5 = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr my_double Euler5 = std::numbers::e;
static constexpr my_float Euler6 = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::e_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::e_v<float>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr my_float Euler6 = std::numbers::e_v<float>;
static constexpr int NotEuler7 = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr int NotEuler7 = std::numbers::e;
static constexpr double InvPi = 1.0 / Pi;
- // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::inv_pi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::inv_pi' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr double InvPi = std::numbers::inv_pi;
static constexpr my_float Actually2MyFloat = 2;
bar::sqrt(Actually2MyFloat);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2_v<float>;
sink(MY_PI);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::pi);
constexpr static auto One = 1;
constexpr static auto Two = 2;
bar::sqrt(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
bar::sqrt(Two);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
bar::sqrt(2.0);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
auto Not2 = 2;
@@ -128,157 +128,157 @@ void foo(){
const auto Actually2 = 2;
bar::sqrt(Actually2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
exp(1);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::e;
exp(One);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::e;
exp(1.00000000000001);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::e;
log2(exp(1));
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
log2(Euler);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
log2(bar::e);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
log2(Euler5);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
log2(Euler6);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e_v<float>;
log2(NotEuler7);
auto log2e = 1.4426950;
- // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer 'std::numbers::log2e' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
// CHECK-FIXES: auto log2e = std::numbers::log2e;
floatSink(log2(Euler));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<float>(log2(Euler)));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(1.4426950);
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<float>(1.4426950));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(log2(static_cast<float>(Euler)));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<float>(log2(static_cast<float>(Euler))));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<float>(log2(static_cast<int>(Euler))));
floatSink(static_cast<int>(log2(static_cast<float>(Euler))));
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
floatSink(1.4426950F);
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<double>(1.4426950F));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<int>(1.4426950F));
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
// CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
log10(exp(1));
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log10e;
log10(Euler);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log10e;
log10(bar::e);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log10e;
auto log10e = .434294;
- // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::log10e' to this literal, differs by '4.82e-07' [modernize-use-std-numbers]
// CHECK-FIXES: auto log10e = std::numbers::log10e;
auto egamma = 0.5772156 * 42;
- // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::egamma' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::egamma' to this literal, differs by '6.49e-08' [modernize-use-std-numbers]
// CHECK-FIXES: auto egamma = std::numbers::egamma * 42;
sink(InvPi);
sink(1 / Pi);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_pi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_pi' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_pi);
sink(1 / bar::sqrt(Pi));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
sink(1 / bar::sqrt(MY_PI));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
log(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::ln2;
log(10);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::ln10;
bar::sqrt(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
sink(1 / bar::sqrt(3));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrt3);
sink(INV_SQRT3);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this macro [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrt3);
const auto inv_sqrt3f = .577350269F;
- // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::inv_sqrt3_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::inv_sqrt3_v<float>' to this literal, differs by '1.04e-08' [modernize-use-std-numbers]
// CHECK-FIXES: const auto inv_sqrt3f = std::numbers::inv_sqrt3_v<float>;
bar::sqrt(3);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt3;
auto somePhi = 1.6180339;
- // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
// CHECK-FIXES: auto somePhi = std::numbers::phi;
sink(Phi);
@@ -286,11 +286,11 @@ void foo(){
sink((42 + bar::sqrt(5)) / 2);
sink((1 + bar::sqrt(5)) / 2);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::phi);
sink((bar::sqrt(5.0F) + 1) / 2);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::phi_v<float>);
}
@@ -299,20 +299,20 @@ void foo(){
template <typename T>
void baz(){
static constexpr T Pi = 3.1415926;
- // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr T Pi = std::numbers::pi;
static constexpr T Euler = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr T Euler = std::numbers::e;
static constexpr T Phi = 1.6180339;
- // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr T Phi = std::numbers::phi;
static constexpr T PiCopy = Pi;
static constexpr T PiDefineFromMacro = MY_PI;
- // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr T PiDefineFromMacro = std::numbers::pi;
// not close enough to match value (DiffThreshold)
@@ -321,33 +321,33 @@ void baz(){
static constexpr T Phi2 = 1.61;
static constexpr T Pi3 = 3.1415926L;
- // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::pi_v<long double>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr T Pi3 = std::numbers::pi_v<long double>;
static constexpr T Euler3 = 2.7182818L;
- // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e_v<long double>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e_v<long double>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr T Euler3 = std::numbers::e_v<long double>;
static constexpr T Phi3 = 1.6180339L;
- // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer 'std::numbers::phi_v<long double>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer 'std::numbers::phi_v<long double>' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
// CHECK-FIXES: static constexpr T Phi3 = std::numbers::phi_v<long double>;
static constexpr my_float Actually2MyFloat = 2;
bar::sqrt(Actually2MyFloat);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2_v<float>;
constexpr static T One = 1;
constexpr static T Two = 2;
bar::sqrt(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
bar::sqrt(Two);
bar::sqrt(2.0);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
T Not2 = 2;
@@ -358,47 +358,47 @@ void baz(){
bar::sqrt(Actually2);
exp(1);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::e;
exp(One);
exp(1.00000000000001);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::e;
log2(exp(1));
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
log2(Euler);
log2(bar::e);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log2e;
T log2e = 1.4426950;
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
// CHECK-FIXES: T log2e = std::numbers::log2e;
log10(exp(1));
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log10e;
log10(Euler);
log10(bar::e);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::log10e;
T log10e = .434294;
- // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::log10e' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::log10e' to this literal, differs by '4.82e-07' [modernize-use-std-numbers]
// CHECK-FIXES: T log10e = std::numbers::log10e;
T egamma = 0.5772156 * 42;
- // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::egamma' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::egamma' to this literal, differs by '6.49e-08' [modernize-use-std-numbers]
// CHECK-FIXES: T egamma = std::numbers::egamma * 42;
sink(1 / Pi);
@@ -406,44 +406,44 @@ void baz(){
sink(1 / bar::sqrt(Pi));
sink(1 / bar::sqrt(MY_PI));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
log(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::ln2;
log(10);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::ln10;
bar::sqrt(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt2;
sink(1 / bar::sqrt(3));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' math constant [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::inv_sqrt3);
bar::sqrt(3);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: std::numbers::sqrt3;
T phi = 1.6180339;
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
// CHECK-FIXES: T phi = std::numbers::phi;
sink((42 + bar::sqrt(5)) / 2);
sink((1 + bar::sqrt(5)) / 2);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::phi);
sink((bar::sqrt(5.0F) + 1) / 2);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' math constant [modernize-use-std-numbers]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' to this formula [modernize-use-std-numbers]
// CHECK-FIXES: sink(std::numbers::phi_v<float>);
}
>From b886daf14b3b7bf92345e40431bbdea072acf775 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 11 Nov 2023 00:13:43 +0100
Subject: [PATCH 29/44] add config value for DiffThreshold
---
.../modernize/UseStdNumbersCheck.cpp | 335 ++++++++-------
.../clang-tidy/modernize/UseStdNumbersCheck.h | 3 +
.../checkers/modernize/use-std-numbers.cpp | 384 +++++++++---------
3 files changed, 383 insertions(+), 339 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index cb7579d42a33c..6ac1fcc75c01c 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -42,9 +42,8 @@ using namespace clang::ast_matchers;
using clang::ast_matchers::internal::Matcher;
using llvm::StringRef;
-constexpr auto DiffThreshold = 0.001;
-
-AST_MATCHER_P(clang::FloatingLiteral, near, double, Value) {
+AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double,
+ DiffThreshold) {
return std::abs(Node.getValueAsApproximateDouble() - Value) < DiffThreshold;
}
@@ -75,176 +74,190 @@ AST_MATCHER_P(clang::Expr, anyOfExhaustive,
return FoundMatch;
}
-auto ignoreImplicitAndArithmeticCasting(const Matcher<clang::Expr> Matcher) {
- return expr(
- ignoringImplicit(expr(hasType(qualType(isArithmetic())),
- ignoringParenCasts(ignoringImplicit(Matcher)))));
-}
+// Using this struct to store the 'DiffThreshold' config value to create the
+// matchers without the need to pass 'DiffThreshold' into every matcher.
+// 'DiffThreshold' is needed in the 'near' matcher, which is used for matching
+// the literal of every constant and for formulas' subexpressions that look at
+// literals.
+struct MatchBuilder {
+ auto
+ ignoreImplicitAndArithmeticCasting(const Matcher<clang::Expr> Matcher) const {
+ return expr(
+ ignoringImplicit(expr(hasType(qualType(isArithmetic())),
+ ignoringParenCasts(ignoringImplicit(Matcher)))));
+ }
-auto ignoreImplicitAndFloatingCasting(const Matcher<clang::Expr> Matcher) {
- return expr(
- ignoringImplicit(expr(hasType(qualType(isFloating())),
- ignoringParenCasts(ignoringImplicit(Matcher)))));
-}
+ auto
+ ignoreImplicitAndFloatingCasting(const Matcher<clang::Expr> Matcher) const {
+ return expr(
+ ignoringImplicit(expr(hasType(qualType(isFloating())),
+ ignoringParenCasts(ignoringImplicit(Matcher)))));
+ }
-auto matchMathCall(const StringRef FunctionName,
- const Matcher<clang::Expr> ArgumentMatcher) {
- return expr(ignoreImplicitAndFloatingCasting(
- callExpr(callee(functionDecl(hasName(FunctionName),
- hasParameter(0, hasType(isArithmetic())))),
- hasArgument(0, ArgumentMatcher))));
-}
+ auto matchMathCall(const StringRef FunctionName,
+ const Matcher<clang::Expr> ArgumentMatcher) const {
+ return expr(ignoreImplicitAndFloatingCasting(
+ callExpr(callee(functionDecl(hasName(FunctionName),
+ hasParameter(0, hasType(isArithmetic())))),
+ hasArgument(0, ArgumentMatcher))));
+ }
-auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) {
- return matchMathCall("sqrt", ArgumentMatcher);
-}
+ auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) const {
+ return matchMathCall("sqrt", ArgumentMatcher);
+ }
-// Used for top-level matchers (i.e. the match that replaces Val with its
-// constant).
-//
-// E.g. The matcher of `std::numbers::pi` uses this matcher to look to
-// floatLiterals that have the value of pi.
-//
-// If the match is for a top-level match, we only care about the literal.
-auto matchFloatLiteralNear(const StringRef Constant, const double Val) {
- return expr(
- ignoreImplicitAndFloatingCasting(floatLiteral(near(Val)).bind(Constant)));
-}
+ // Used for top-level matchers (i.e. the match that replaces Val with its
+ // constant).
+ //
+ // E.g. The matcher of `std::numbers::pi` uses this matcher to look to
+ // floatLiterals that have the value of pi.
+ //
+ // If the match is for a top-level match, we only care about the literal.
+ auto matchFloatLiteralNear(const StringRef Constant, const double Val) const {
+ return expr(ignoreImplicitAndFloatingCasting(
+ floatLiteral(near(Val, DiffThreshold)).bind(Constant)));
+ }
-// Used for non-top-level matchers (i.e. matchers that are used as inner
-// matchers for top-level matchers).
-//
-// E.g.: The matcher of `std::numbers::log2e` uses this matcher to check if `e`
-// of `log2(e)` is declared constant and initialized with the value for eulers
-// number.
-//
-// Here, we do care about literals and about DeclRefExprs to variable
-// declarations that are constant and initialized with `Val`. This allows
-// top-level matchers to see through declared constants for their inner matches
-// like the `std::numbers::log2e` matcher.
-auto matchFloatValueNear(const double Val) {
- const auto Float = floatLiteral(near(Val));
-
- const auto Dref = declRefExpr(
- to(varDecl(hasType(qualType(isConstQualified(), isFloating())),
- hasInitializer(ignoreImplicitAndFloatingCasting(Float)))));
- return expr(ignoreImplicitAndFloatingCasting(anyOf(Float, Dref)));
-}
+ // Used for non-top-level matchers (i.e. matchers that are used as inner
+ // matchers for top-level matchers).
+ //
+ // E.g.: The matcher of `std::numbers::log2e` uses this matcher to check if
+ // `e` of `log2(e)` is declared constant and initialized with the value for
+ // eulers number.
+ //
+ // Here, we do care about literals and about DeclRefExprs to variable
+ // declarations that are constant and initialized with `Val`. This allows
+ // top-level matchers to see through declared constants for their inner
+ // matches like the `std::numbers::log2e` matcher.
+ auto matchFloatValueNear(const double Val) const {
+ const auto Float = floatLiteral(near(Val, DiffThreshold));
+
+ const auto Dref = declRefExpr(
+ to(varDecl(hasType(qualType(isConstQualified(), isFloating())),
+ hasInitializer(ignoreImplicitAndFloatingCasting(Float)))));
+ return expr(ignoreImplicitAndFloatingCasting(anyOf(Float, Dref)));
+ }
-auto matchValue(const int64_t ValInt) {
- const auto Int =
- expr(ignoreImplicitAndArithmeticCasting(integerLiteral(equals(ValInt))));
- const auto Float = expr(ignoreImplicitAndFloatingCasting(
- matchFloatValueNear(static_cast<double>(ValInt))));
- const auto Dref = declRefExpr(to(varDecl(
- hasType(qualType(isConstQualified(), isArithmetic())),
- hasInitializer(expr(anyOf(ignoringImplicit(Int),
- ignoreImplicitAndFloatingCasting(Float)))))));
- return expr(anyOf(Int, Float, Dref));
-}
+ auto matchValue(const int64_t ValInt) const {
+ const auto Int = expr(
+ ignoreImplicitAndArithmeticCasting(integerLiteral(equals(ValInt))));
+ const auto Float = expr(ignoreImplicitAndFloatingCasting(
+ matchFloatValueNear(static_cast<double>(ValInt))));
+ const auto Dref = declRefExpr(to(varDecl(
+ hasType(qualType(isConstQualified(), isArithmetic())),
+ hasInitializer(expr(anyOf(ignoringImplicit(Int),
+ ignoreImplicitAndFloatingCasting(Float)))))));
+ return expr(anyOf(Int, Float, Dref));
+ }
-auto match1Div(const Matcher<clang::Expr> Match) {
- return binaryOperator(hasOperatorName("/"), hasLHS(matchValue(1)),
- hasRHS(ignoringImplicit(Match)));
-}
+ auto match1Div(const Matcher<clang::Expr> Match) const {
+ return binaryOperator(hasOperatorName("/"), hasLHS(matchValue(1)),
+ hasRHS(ignoringImplicit(Match)));
+ }
-auto matchEuler() {
- return expr(anyOf(matchFloatValueNear(llvm::numbers::e),
- matchMathCall("exp", matchValue(1))));
-}
-auto matchEulerTopLevel() {
- return expr(anyOf(matchFloatLiteralNear("e_literal", llvm::numbers::e),
- matchMathCall("exp", matchValue(1)).bind("e_pattern")))
- .bind("e");
-}
+ auto matchEuler() const {
+ return expr(anyOf(matchFloatValueNear(llvm::numbers::e),
+ matchMathCall("exp", matchValue(1))));
+ }
+ auto matchEulerTopLevel() const {
+ return expr(anyOf(matchFloatLiteralNear("e_literal", llvm::numbers::e),
+ matchMathCall("exp", matchValue(1)).bind("e_pattern")))
+ .bind("e");
+ }
-auto matchLog2Euler() {
- return expr(
- anyOf(matchFloatLiteralNear("log2e_literal", llvm::numbers::log2e),
+ auto matchLog2Euler() const {
+ return expr(
+ anyOf(
+ matchFloatLiteralNear("log2e_literal", llvm::numbers::log2e),
matchMathCall("log2", matchEuler()).bind("log2e_pattern")))
- .bind("log2e");
-}
+ .bind("log2e");
+ }
-auto matchLog10Euler() {
- return expr(
- anyOf(
- matchFloatLiteralNear("log10e_literal", llvm::numbers::log10e),
- matchMathCall("log10", matchEuler()).bind("log10e_pattern")))
- .bind("log10e");
-}
+ auto matchLog10Euler() const {
+ return expr(
+ anyOf(
+ matchFloatLiteralNear("log10e_literal",
+ llvm::numbers::log10e),
+ matchMathCall("log10", matchEuler()).bind("log10e_pattern")))
+ .bind("log10e");
+ }
-auto matchPi() { return matchFloatValueNear(llvm::numbers::pi); }
-auto matchPiTopLevel() {
- return matchFloatLiteralNear("pi_literal", llvm::numbers::pi).bind("pi");
-}
+ auto matchPi() const { return matchFloatValueNear(llvm::numbers::pi); }
+ auto matchPiTopLevel() const {
+ return matchFloatLiteralNear("pi_literal", llvm::numbers::pi).bind("pi");
+ }
-auto matchEgamma() {
- return matchFloatLiteralNear("egamma_literal", llvm::numbers::egamma)
- .bind("egamma");
-}
+ auto matchEgamma() const {
+ return matchFloatLiteralNear("egamma_literal", llvm::numbers::egamma)
+ .bind("egamma");
+ }
-auto matchInvPi() {
- return expr(anyOf(matchFloatLiteralNear("inv_pi_literal",
- llvm::numbers::inv_pi),
- match1Div(matchPi()).bind("inv_pi_pattern")))
- .bind("inv_pi");
-}
+ auto matchInvPi() const {
+ return expr(anyOf(matchFloatLiteralNear("inv_pi_literal",
+ llvm::numbers::inv_pi),
+ match1Div(matchPi()).bind("inv_pi_pattern")))
+ .bind("inv_pi");
+ }
-auto matchInvSqrtPi() {
- return expr(anyOf(matchFloatLiteralNear("inv_sqrtpi_literal",
+ auto matchInvSqrtPi() const {
+ return expr(anyOf(
+ matchFloatLiteralNear("inv_sqrtpi_literal",
llvm::numbers::inv_sqrtpi),
match1Div(matchSqrt(matchPi())).bind("inv_sqrtpi_pattern")))
- .bind("inv_sqrtpi");
-}
+ .bind("inv_sqrtpi");
+ }
-auto matchLn2() {
- return expr(anyOf(matchFloatLiteralNear("ln2_literal", llvm::numbers::ln2),
- matchMathCall("log", ignoringImplicit(matchValue(2)))
- .bind("ln2_pattern")))
- .bind("ln2");
-}
+ auto matchLn2() const {
+ return expr(anyOf(matchFloatLiteralNear("ln2_literal", llvm::numbers::ln2),
+ matchMathCall("log", ignoringImplicit(matchValue(2)))
+ .bind("ln2_pattern")))
+ .bind("ln2");
+ }
-auto machterLn10() {
- return expr(anyOf(matchFloatLiteralNear("ln10_literal", llvm::numbers::ln10),
- matchMathCall("log", ignoringImplicit(matchValue(10)))
- .bind("ln10_pattern")))
- .bind("ln10");
-}
+ auto machterLn10() const {
+ return expr(
+ anyOf(matchFloatLiteralNear("ln10_literal", llvm::numbers::ln10),
+ matchMathCall("log", ignoringImplicit(matchValue(10)))
+ .bind("ln10_pattern")))
+ .bind("ln10");
+ }
-auto matchSqrt2() {
- return expr(
- anyOf(matchFloatLiteralNear("sqrt2_literal", llvm::numbers::sqrt2),
- matchSqrt(matchValue(2)).bind("sqrt2_pattern")))
- .bind("sqrt2");
-}
+ auto matchSqrt2() const {
+ return expr(anyOf(matchFloatLiteralNear("sqrt2_literal",
+ llvm::numbers::sqrt2),
+ matchSqrt(matchValue(2)).bind("sqrt2_pattern")))
+ .bind("sqrt2");
+ }
-auto matchSqrt3() {
- return expr(
- anyOf(matchFloatLiteralNear("sqrt3_literal", llvm::numbers::sqrt3),
- matchSqrt(matchValue(3)).bind("sqrt3_pattern")))
- .bind("sqrt3");
-}
+ auto matchSqrt3() const {
+ return expr(anyOf(matchFloatLiteralNear("sqrt3_literal",
+ llvm::numbers::sqrt3),
+ matchSqrt(matchValue(3)).bind("sqrt3_pattern")))
+ .bind("sqrt3");
+ }
-auto matchInvSqrt3() {
- return expr(
- anyOf(
- matchFloatLiteralNear("inv_sqrt3_literal",
- llvm::numbers::inv_sqrt3),
- match1Div(matchSqrt(matchValue(3))).bind("inv_sqrt3_pattern")))
- .bind("inv_sqrt3");
-}
+ auto matchInvSqrt3() const {
+ return expr(anyOf(matchFloatLiteralNear("inv_sqrt3_literal",
+ llvm::numbers::inv_sqrt3),
+ match1Div(matchSqrt(matchValue(3)))
+ .bind("inv_sqrt3_pattern")))
+ .bind("inv_sqrt3");
+ }
-auto matchPhi() {
- const auto PhiFormula = binaryOperator(
- hasOperatorName("/"),
- hasLHS(parenExpr(has(binaryOperator(
- hasOperatorName("+"), hasEitherOperand(matchValue(1)),
- hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
- hasRHS(matchValue(2)));
- return expr(anyOf(PhiFormula.bind("phi_pattern"),
- matchFloatLiteralNear("phi_literal", llvm::numbers::phi)))
- .bind("phi");
-}
+ auto matchPhi() const {
+ const auto PhiFormula = binaryOperator(
+ hasOperatorName("/"),
+ hasLHS(parenExpr(has(binaryOperator(
+ hasOperatorName("+"), hasEitherOperand(matchValue(1)),
+ hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
+ hasRHS(matchValue(2)));
+ return expr(anyOf(PhiFormula.bind("phi_pattern"),
+ matchFloatLiteralNear("phi_literal", llvm::numbers::phi)))
+ .bind("phi");
+ }
+
+ double DiffThreshold;
+};
std::string getCode(const StringRef Constant, const bool IsFloat,
const bool IsLongDouble) {
@@ -286,14 +299,26 @@ UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name,
: ClangTidyCheck(Name, Context),
IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
- areDiagsSelfContained()) {}
+ areDiagsSelfContained()) {
+ DiffThresholdString = Options.get("DiffThreshold", "0.001");
+ if (DiffThresholdString.getAsDouble(DiffThreshold)) {
+ configurationDiag(
+ "Invalid DiffThreshold config value: '%0', expected a double")
+ << DiffThresholdString;
+ DiffThreshold = 0.001;
+ }
+}
void UseStdNumbersCheck::registerMatchers(MatchFinder *Finder) {
+ const auto Matches = MatchBuilder{DiffThreshold};
static const auto ConstantMatchers = {
- matchLog2Euler(), matchLog10Euler(), matchEulerTopLevel(), matchEgamma(),
- matchInvSqrtPi(), matchInvPi(), matchPiTopLevel(), matchLn2(),
- machterLn10(), matchSqrt2(), matchInvSqrt3(), matchSqrt3(),
- matchPhi(),
+ Matches.matchLog2Euler(), Matches.matchLog10Euler(),
+ Matches.matchEulerTopLevel(), Matches.matchEgamma(),
+ Matches.matchInvSqrtPi(), Matches.matchInvPi(),
+ Matches.matchPiTopLevel(), Matches.matchLn2(),
+ Matches.machterLn10(), Matches.matchSqrt2(),
+ Matches.matchInvSqrt3(), Matches.matchSqrt3(),
+ Matches.matchPhi(),
};
Finder->addMatcher(
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
index da52f2b9ab4ce..ef63987daea84 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
@@ -35,10 +35,13 @@ class UseStdNumbersCheck : public ClangTidyCheck {
Preprocessor *ModuleExpanderPP) override;
void storeOptions(ClangTidyOptions::OptionMap &Opts) override {
Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+ Options.store(Opts, "DiffThreshold", DiffThresholdString);
}
private:
utils::IncludeInserter IncludeInserter;
+ StringRef DiffThresholdString;
+ double DiffThreshold;
};
} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 71f01ffaeb8df..9b292e920e289 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -1,6 +1,7 @@
-// RUN: %check_clang_tidy -std=c++20 %s modernize-use-std-numbers %t
+// RUN: %check_clang_tidy -check-suffix=ALL -std=c++20 %s modernize-use-std-numbers %t
+// RUN: %check_clang_tidy -check-suffix=ALL,IMPRECISE -std=c++20 %s modernize-use-std-numbers %t -- -config="{CheckOptions: { modernize-use-std-numbers.DiffThreshold: 0.01 }}"
-// CHECK-FIXES: #include <numbers>
+// CHECK-FIXES-ALL: #include <numbers>
namespace bar {
double sqrt(double Arg);
@@ -9,8 +10,8 @@ namespace bar {
auto sqrt(T val) { return sqrt(static_cast<double>(val)); }
static constexpr double e = 2.718281828459045235360287471352662497757247093;
- // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e' to this literal, differs by '0.00e+00' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr double e = std::numbers::e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e' to this literal, differs by '0.00e+00' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr double e = std::numbers::e;
}
double exp(double Arg);
@@ -37,90 +38,100 @@ using my_float = float;
void foo(){
static constexpr double Pi = 3.1415926;
- // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr double Pi = std::numbers::pi;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:34: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr double Pi = std::numbers::pi;
static constexpr double Euler = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr double Euler = std::numbers::e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:37: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr double Euler = std::numbers::e;
static constexpr double Phi = 1.6180339;
- // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr double Phi = std::numbers::phi;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:35: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr double Phi = std::numbers::phi;
static constexpr double PiCopy = Pi;
static constexpr double PiDefineFromMacro = MY_PI;
- // CHECK-MESSAGES: :[[@LINE-1]]:49: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr double PiDefineFromMacro = std::numbers::pi;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:49: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr double PiDefineFromMacro = std::numbers::pi;
- // not close enough to match value (DiffThreshold)
static constexpr double Pi2 = 3.14;
+ // CHECK-MESSAGES-IMPRECISE: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi' to this literal, differs by '1.59e-03' [modernize-use-std-numbers]
+ // CHECK-FIXES-IMPRECISE: static constexpr double Pi2 = std::numbers::pi;
static constexpr double Euler2 = 2.71;
+ // CHECK-MESSAGES-IMPRECISE: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '8.28e-03' [modernize-use-std-numbers]
+ // CHECK-FIXES-IMPRECISE: static constexpr double Euler2 = std::numbers::e;
static constexpr double Phi2 = 1.61;
+ // CHECK-MESSAGES-IMPRECISE: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi' to this literal, differs by '8.03e-03' [modernize-use-std-numbers]
+ // CHECK-FIXES-IMPRECISE: static constexpr double Phi2 = std::numbers::phi;
static constexpr double Pi3 = 3.1415926L;
- // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr double Pi3 = std::numbers::pi;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr double Pi3 = std::numbers::pi;
static constexpr double Euler3 = 2.7182818L;
- // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr double Euler3 = std::numbers::e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr double Euler3 = std::numbers::e;
static constexpr double Phi3 = 1.6180339L;
- // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr double Phi3 = std::numbers::phi;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr double Phi3 = std::numbers::phi;
static constexpr long double Pi4 = 3.1415926L;
- // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr long double Pi4 = std::numbers::pi_v<long double>;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:40: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr long double Pi4 = std::numbers::pi_v<long double>;
static constexpr long double Euler4 = 2.7182818L;
- // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer 'std::numbers::e_v<long double>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr long double Euler4 = std::numbers::e_v<long double>;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:43: warning: prefer 'std::numbers::e_v<long double>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr long double Euler4 = std::numbers::e_v<long double>;
static constexpr long double Phi4 = 1.6180339L;
- // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::phi_v<long double>' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:41: warning: prefer 'std::numbers::phi_v<long double>' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr long double Phi4 = std::numbers::phi_v<long double>;
static constexpr my_double Euler5 = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr my_double Euler5 = std::numbers::e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:41: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr my_double Euler5 = std::numbers::e;
static constexpr my_float Euler6 = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer 'std::numbers::e_v<float>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr my_float Euler6 = std::numbers::e_v<float>;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:40: warning: prefer 'std::numbers::e_v<float>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr my_float Euler6 = std::numbers::e_v<float>;
static constexpr int NotEuler7 = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr int NotEuler7 = std::numbers::e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr int NotEuler7 = std::numbers::e;
static constexpr double InvPi = 1.0 / Pi;
- // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer 'std::numbers::inv_pi' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr double InvPi = std::numbers::inv_pi;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:37: warning: prefer 'std::numbers::inv_pi' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr double InvPi = std::numbers::inv_pi;
static constexpr my_float Actually2MyFloat = 2;
bar::sqrt(Actually2MyFloat);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::sqrt2_v<float>;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::sqrt2_v<float>;
sink(MY_PI);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: sink(std::numbers::pi);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: sink(std::numbers::pi);
+
+ auto X = 42.0;
+ auto Y = X * 3.14;
+ // CHECK-MESSAGES-IMPRECISE: :[[@LINE-1]]:18: warning: prefer 'std::numbers::pi' to this literal, differs by '1.59e-03' [modernize-use-std-numbers]
+ // CHECK-FIXES-IMPRECISE: auto Y = X * std::numbers::pi;
constexpr static auto One = 1;
constexpr static auto Two = 2;
bar::sqrt(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::sqrt2;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::sqrt2;
bar::sqrt(Two);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::sqrt2;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::sqrt2;
bar::sqrt(2.0);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::sqrt2;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::sqrt2;
auto Not2 = 2;
Not2 = 42;
@@ -128,170 +139,170 @@ void foo(){
const auto Actually2 = 2;
bar::sqrt(Actually2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::sqrt2;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::sqrt2;
exp(1);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::e;
exp(One);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::e;
exp(1.00000000000001);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::e;
log2(exp(1));
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::log2e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES-ALL: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::log2e;
log2(Euler);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::log2e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::log2e;
log2(bar::e);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::log2e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::log2e;
log2(Euler5);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::log2e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::log2e;
log2(Euler6);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::log2e_v<float>;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::log2e_v<float>;
log2(NotEuler7);
auto log2e = 1.4426950;
- // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer 'std::numbers::log2e' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: auto log2e = std::numbers::log2e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:18: warning: prefer 'std::numbers::log2e' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: auto log2e = std::numbers::log2e;
floatSink(log2(Euler));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<float>(log2(Euler)));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
floatSink(1.4426950);
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<float>(1.4426950));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
floatSink(log2(static_cast<float>(Euler)));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<float>(log2(static_cast<float>(Euler))));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<float>(log2(static_cast<int>(Euler))));
floatSink(static_cast<int>(log2(static_cast<float>(Euler))));
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
floatSink(1.4426950F);
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<double>(1.4426950F));
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: floatSink(std::numbers::log2e_v<float>);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<int>(1.4426950F));
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: floatSink(static_cast<int>(std::numbers::log2e_v<float>));
log10(exp(1));
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::log10e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES-ALL: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::log10e;
log10(Euler);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::log10e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::log10e;
log10(bar::e);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::log10e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::log10e;
auto log10e = .434294;
- // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::log10e' to this literal, differs by '4.82e-07' [modernize-use-std-numbers]
- // CHECK-FIXES: auto log10e = std::numbers::log10e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:19: warning: prefer 'std::numbers::log10e' to this literal, differs by '4.82e-07' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: auto log10e = std::numbers::log10e;
auto egamma = 0.5772156 * 42;
- // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer 'std::numbers::egamma' to this literal, differs by '6.49e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: auto egamma = std::numbers::egamma * 42;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:19: warning: prefer 'std::numbers::egamma' to this literal, differs by '6.49e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: auto egamma = std::numbers::egamma * 42;
sink(InvPi);
sink(1 / Pi);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_pi' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: sink(std::numbers::inv_pi);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_pi' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: sink(std::numbers::inv_pi);
sink(1 / bar::sqrt(Pi));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: sink(std::numbers::inv_sqrtpi);
sink(1 / bar::sqrt(MY_PI));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES-ALL: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: sink(std::numbers::inv_sqrtpi);
log(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::ln2;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::ln2;
log(10);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::ln10;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::ln10;
bar::sqrt(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::sqrt2;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::sqrt2;
sink(1 / bar::sqrt(3));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this formula [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES-ALL: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: sink(std::numbers::inv_sqrt3);
sink(INV_SQRT3);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this macro [modernize-use-std-numbers]
- // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this macro [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: sink(std::numbers::inv_sqrt3);
const auto inv_sqrt3f = .577350269F;
- // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::inv_sqrt3_v<float>' to this literal, differs by '1.04e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: const auto inv_sqrt3f = std::numbers::inv_sqrt3_v<float>;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:29: warning: prefer 'std::numbers::inv_sqrt3_v<float>' to this literal, differs by '1.04e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: const auto inv_sqrt3f = std::numbers::inv_sqrt3_v<float>;
bar::sqrt(3);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::sqrt3;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::sqrt3;
auto somePhi = 1.6180339;
- // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: auto somePhi = std::numbers::phi;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:20: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: auto somePhi = std::numbers::phi;
sink(Phi);
sink((42 + bar::sqrt(5)) / 2);
sink((1 + bar::sqrt(5)) / 2);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: sink(std::numbers::phi);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: sink(std::numbers::phi);
sink((bar::sqrt(5.0F) + 1) / 2);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: sink(std::numbers::phi_v<float>);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: sink(std::numbers::phi_v<float>);
}
@@ -299,56 +310,61 @@ void foo(){
template <typename T>
void baz(){
static constexpr T Pi = 3.1415926;
- // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr T Pi = std::numbers::pi;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:29: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr T Pi = std::numbers::pi;
static constexpr T Euler = 2.7182818;
- // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr T Euler = std::numbers::e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:32: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr T Euler = std::numbers::e;
static constexpr T Phi = 1.6180339;
- // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr T Phi = std::numbers::phi;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:30: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr T Phi = std::numbers::phi;
static constexpr T PiCopy = Pi;
static constexpr T PiDefineFromMacro = MY_PI;
- // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr T PiDefineFromMacro = std::numbers::pi;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:44: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr T PiDefineFromMacro = std::numbers::pi;
- // not close enough to match value (DiffThreshold)
static constexpr T Pi2 = 3.14;
+ // CHECK-MESSAGES-IMPRECISE: :[[@LINE-1]]:30: warning: prefer 'std::numbers::pi' to this literal, differs by '1.59e-03' [modernize-use-std-numbers]
+ // CHECK-FIXES-IMPRECISE: static constexpr T Pi2 = std::numbers::pi;
static constexpr T Euler2 = 2.71;
+ // CHECK-MESSAGES-IMPRECISE: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e' to this literal, differs by '8.28e-03' [modernize-use-std-numbers]
+ // CHECK-FIXES-IMPRECISE: static constexpr T Euler2 = std::numbers::e;
static constexpr T Phi2 = 1.61;
+ // CHECK-MESSAGES-IMPRECISE: :[[@LINE-1]]:31: warning: prefer 'std::numbers::phi' to this literal, differs by '8.03e-03' [modernize-use-std-numbers]
+ // CHECK-FIXES-IMPRECISE: static constexpr T Phi2 = std::numbers::phi;
static constexpr T Pi3 = 3.1415926L;
- // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr T Pi3 = std::numbers::pi_v<long double>;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:30: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr T Pi3 = std::numbers::pi_v<long double>;
static constexpr T Euler3 = 2.7182818L;
- // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e_v<long double>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr T Euler3 = std::numbers::e_v<long double>;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:33: warning: prefer 'std::numbers::e_v<long double>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr T Euler3 = std::numbers::e_v<long double>;
static constexpr T Phi3 = 1.6180339L;
- // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer 'std::numbers::phi_v<long double>' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: static constexpr T Phi3 = std::numbers::phi_v<long double>;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:31: warning: prefer 'std::numbers::phi_v<long double>' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr T Phi3 = std::numbers::phi_v<long double>;
static constexpr my_float Actually2MyFloat = 2;
bar::sqrt(Actually2MyFloat);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::sqrt2_v<float>;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2_v<float>' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::sqrt2_v<float>;
constexpr static T One = 1;
constexpr static T Two = 2;
bar::sqrt(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::sqrt2;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::sqrt2;
bar::sqrt(Two);
bar::sqrt(2.0);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::sqrt2;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::sqrt2;
T Not2 = 2;
Not2 = 42;
@@ -358,93 +374,93 @@ void baz(){
bar::sqrt(Actually2);
exp(1);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::e;
exp(One);
exp(1.00000000000001);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::e;
log2(exp(1));
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::log2e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES-ALL: :[[@LINE-2]]:10: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::log2e;
log2(Euler);
log2(bar::e);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::log2e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::log2e;
T log2e = 1.4426950;
- // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: T log2e = std::numbers::log2e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: T log2e = std::numbers::log2e;
log10(exp(1));
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::log10e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES-ALL: :[[@LINE-2]]:11: warning: prefer 'std::numbers::e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::log10e;
log10(Euler);
log10(bar::e);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::log10e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::log10e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::log10e;
T log10e = .434294;
- // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::log10e' to this literal, differs by '4.82e-07' [modernize-use-std-numbers]
- // CHECK-FIXES: T log10e = std::numbers::log10e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:16: warning: prefer 'std::numbers::log10e' to this literal, differs by '4.82e-07' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: T log10e = std::numbers::log10e;
T egamma = 0.5772156 * 42;
- // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer 'std::numbers::egamma' to this literal, differs by '6.49e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: T egamma = std::numbers::egamma * 42;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:16: warning: prefer 'std::numbers::egamma' to this literal, differs by '6.49e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: T egamma = std::numbers::egamma * 42;
sink(1 / Pi);
sink(1 / bar::sqrt(Pi));
sink(1 / bar::sqrt(MY_PI));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: sink(std::numbers::inv_sqrtpi);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrtpi' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES-ALL: :[[@LINE-2]]:24: warning: prefer 'std::numbers::pi' to this macro, differs by '5.36e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: sink(std::numbers::inv_sqrtpi);
log(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::ln2;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln2' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::ln2;
log(10);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::ln10;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::ln10' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::ln10;
bar::sqrt(2);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::sqrt2;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt2' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::sqrt2;
sink(1 / bar::sqrt(3));
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this formula [modernize-use-std-numbers]
- // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: sink(std::numbers::inv_sqrt3);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this formula [modernize-use-std-numbers]
+ // CHECK-MESSAGES-ALL: :[[@LINE-2]]:14: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: sink(std::numbers::inv_sqrt3);
bar::sqrt(3);
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: std::numbers::sqrt3;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:5: warning: prefer 'std::numbers::sqrt3' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: std::numbers::sqrt3;
T phi = 1.6180339;
- // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
- // CHECK-FIXES: T phi = std::numbers::phi;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: T phi = std::numbers::phi;
sink((42 + bar::sqrt(5)) / 2);
sink((1 + bar::sqrt(5)) / 2);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: sink(std::numbers::phi);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: sink(std::numbers::phi);
sink((bar::sqrt(5.0F) + 1) / 2);
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES: sink(std::numbers::phi_v<float>);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::phi_v<float>' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: sink(std::numbers::phi_v<float>);
}
template <typename T>
>From d25045a67aff19718a01d8f438016946aa870bb8 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 11 Nov 2023 02:56:44 +0100
Subject: [PATCH 30/44] use TK_IgnoreUnlessSpelledInSource
- makes some matchers a little bit more readable
- removes the need for the double `ignoringImplicit`
in the custom ignoringParenAnd_Casting
---
.../modernize/UseStdNumbersCheck.cpp | 48 +++++++++----------
1 file changed, 23 insertions(+), 25 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 6ac1fcc75c01c..0246a035b394b 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -9,6 +9,7 @@
#include "UseStdNumbersCheck.h"
#include "../ClangTidyDiagnosticConsumer.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Stmt.h"
@@ -81,22 +82,18 @@ AST_MATCHER_P(clang::Expr, anyOfExhaustive,
// literals.
struct MatchBuilder {
auto
- ignoreImplicitAndArithmeticCasting(const Matcher<clang::Expr> Matcher) const {
- return expr(
- ignoringImplicit(expr(hasType(qualType(isArithmetic())),
- ignoringParenCasts(ignoringImplicit(Matcher)))));
+ ignoreParenAndArithmeticCasting(const Matcher<clang::Expr> Matcher) const {
+ return expr(hasType(qualType(isArithmetic())),
+ ignoringParenCasts((Matcher)));
}
- auto
- ignoreImplicitAndFloatingCasting(const Matcher<clang::Expr> Matcher) const {
- return expr(
- ignoringImplicit(expr(hasType(qualType(isFloating())),
- ignoringParenCasts(ignoringImplicit(Matcher)))));
+ auto ignoreParenAndFloatingCasting(const Matcher<clang::Expr> Matcher) const {
+ return expr(hasType(qualType(isFloating())), ignoringParenCasts((Matcher)));
}
auto matchMathCall(const StringRef FunctionName,
const Matcher<clang::Expr> ArgumentMatcher) const {
- return expr(ignoreImplicitAndFloatingCasting(
+ return expr(ignoreParenAndFloatingCasting(
callExpr(callee(functionDecl(hasName(FunctionName),
hasParameter(0, hasType(isArithmetic())))),
hasArgument(0, ArgumentMatcher))));
@@ -114,7 +111,7 @@ struct MatchBuilder {
//
// If the match is for a top-level match, we only care about the literal.
auto matchFloatLiteralNear(const StringRef Constant, const double Val) const {
- return expr(ignoreImplicitAndFloatingCasting(
+ return expr(ignoreParenAndFloatingCasting(
floatLiteral(near(Val, DiffThreshold)).bind(Constant)));
}
@@ -134,25 +131,25 @@ struct MatchBuilder {
const auto Dref = declRefExpr(
to(varDecl(hasType(qualType(isConstQualified(), isFloating())),
- hasInitializer(ignoreImplicitAndFloatingCasting(Float)))));
- return expr(ignoreImplicitAndFloatingCasting(anyOf(Float, Dref)));
+ hasInitializer(ignoreParenAndFloatingCasting(Float)))));
+ return expr(ignoreParenAndFloatingCasting(anyOf(Float, Dref)));
}
auto matchValue(const int64_t ValInt) const {
- const auto Int = expr(
- ignoreImplicitAndArithmeticCasting(integerLiteral(equals(ValInt))));
- const auto Float = expr(ignoreImplicitAndFloatingCasting(
+ const auto Int =
+ expr(ignoreParenAndArithmeticCasting(integerLiteral(equals(ValInt))));
+ const auto Float = expr(ignoreParenAndFloatingCasting(
matchFloatValueNear(static_cast<double>(ValInt))));
const auto Dref = declRefExpr(to(varDecl(
hasType(qualType(isConstQualified(), isArithmetic())),
hasInitializer(expr(anyOf(ignoringImplicit(Int),
- ignoreImplicitAndFloatingCasting(Float)))))));
+ ignoreParenAndFloatingCasting(Float)))))));
return expr(anyOf(Int, Float, Dref));
}
auto match1Div(const Matcher<clang::Expr> Match) const {
return binaryOperator(hasOperatorName("/"), hasLHS(matchValue(1)),
- hasRHS(ignoringImplicit(Match)));
+ hasRHS(Match));
}
auto matchEuler() const {
@@ -209,16 +206,14 @@ struct MatchBuilder {
auto matchLn2() const {
return expr(anyOf(matchFloatLiteralNear("ln2_literal", llvm::numbers::ln2),
- matchMathCall("log", ignoringImplicit(matchValue(2)))
- .bind("ln2_pattern")))
+ matchMathCall("log", matchValue(2)).bind("ln2_pattern")))
.bind("ln2");
}
auto machterLn10() const {
return expr(
anyOf(matchFloatLiteralNear("ln10_literal", llvm::numbers::ln10),
- matchMathCall("log", ignoringImplicit(matchValue(10)))
- .bind("ln10_pattern")))
+ matchMathCall("log", matchValue(10)).bind("ln10_pattern")))
.bind("ln10");
}
@@ -247,9 +242,9 @@ struct MatchBuilder {
auto matchPhi() const {
const auto PhiFormula = binaryOperator(
hasOperatorName("/"),
- hasLHS(parenExpr(has(binaryOperator(
+ hasLHS(binaryOperator(
hasOperatorName("+"), hasEitherOperand(matchValue(1)),
- hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))),
+ hasEitherOperand(matchMathCall("sqrt", matchValue(5))))),
hasRHS(matchValue(2)));
return expr(anyOf(PhiFormula.bind("phi_pattern"),
matchFloatLiteralNear("phi_literal", llvm::numbers::phi)))
@@ -321,8 +316,11 @@ void UseStdNumbersCheck::registerMatchers(MatchFinder *Finder) {
Matches.matchPhi(),
};
+ // Using 'TK_IgnoreUnlessSpelledInSource' here instead of at the check level
+ // to figure out what the type is that the matched constants are used as.
Finder->addMatcher(
- expr(anyOfExhaustive(ConstantMatchers),
+ expr(traverse(TK_IgnoreUnlessSpelledInSource,
+ expr(anyOfExhaustive(ConstantMatchers))),
unless(isInTemplateInstantiation()),
unless(hasParent(expr(
anyOf(implicitCastExpr(hasImplicitDestinationType(isFloating())),
>From 8343233c24d5fd0076002c0b025fe440515fab8c Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 16 Nov 2023 03:40:25 +0100
Subject: [PATCH 31/44] rm duplicate canonicalization of expr type
---
.../clang-tidy/modernize/UseStdNumbersCheck.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 0246a035b394b..c510ddfd5acf5 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -325,10 +325,10 @@ void UseStdNumbersCheck::registerMatchers(MatchFinder *Finder) {
unless(hasParent(expr(
anyOf(implicitCastExpr(hasImplicitDestinationType(isFloating())),
explicitCastExpr(hasDestinationType(isFloating())))))),
- hasType(qualType(hasCanonicalType(hasCanonicalTypeUnqualified(anyOf(
- qualType(asString("float")).bind("float"),
- qualType(asString("double")),
- qualType(asString("long double")).bind("long double"))))))),
+ hasType(qualType(hasCanonicalTypeUnqualified(
+ anyOf(qualType(asString("float")).bind("float"),
+ qualType(asString("double")),
+ qualType(asString("long double")).bind("long double")))))),
this);
}
>From b802286ce9e672cd4017be488f69d6bb28d91080 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 16 Nov 2023 03:50:32 +0100
Subject: [PATCH 32/44] rm not needed parens
---
.../clang-tidy/modernize/UseStdNumbersCheck.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index c510ddfd5acf5..6c46d504d346e 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -83,12 +83,11 @@ AST_MATCHER_P(clang::Expr, anyOfExhaustive,
struct MatchBuilder {
auto
ignoreParenAndArithmeticCasting(const Matcher<clang::Expr> Matcher) const {
- return expr(hasType(qualType(isArithmetic())),
- ignoringParenCasts((Matcher)));
+ return expr(hasType(qualType(isArithmetic())), ignoringParenCasts(Matcher));
}
auto ignoreParenAndFloatingCasting(const Matcher<clang::Expr> Matcher) const {
- return expr(hasType(qualType(isFloating())), ignoringParenCasts((Matcher)));
+ return expr(hasType(qualType(isFloating())), ignoringParenCasts(Matcher));
}
auto matchMathCall(const StringRef FunctionName,
>From 30ff6eecd23756e9465187c7546ba1bc833dd213 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 16 Nov 2023 03:51:45 +0100
Subject: [PATCH 33/44] declare PatternBindString in the if-init
---
clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 6c46d504d346e..0dfcfa8d23d52 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -391,8 +391,8 @@ void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
continue;
}
- const auto PatternBindString = (ConstantName + "_pattern").str();
- if (Result.Nodes.getNodeAs<Expr>(PatternBindString) != nullptr) {
+ if (const auto PatternBindString = (ConstantName + "_pattern").str();
+ Result.Nodes.getNodeAs<Expr>(PatternBindString) != nullptr) {
const auto Code = getCode(ConstantName, IsFloat, IsLongDouble);
diag(Range.getBegin(), "prefer '%0' to this %select{formula|macro}1")
<< Code << IsMacro << FixItHint::CreateReplacement(Range, Code);
>From b5803cdde1efccb44201519f58335d3d94ef2103 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 16 Nov 2023 03:53:45 +0100
Subject: [PATCH 34/44] more const parameters
---
.../clang-tidy/modernize/UseStdNumbersCheck.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 0dfcfa8d23d52..513d6468399d3 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -303,7 +303,7 @@ UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name,
}
}
-void UseStdNumbersCheck::registerMatchers(MatchFinder *Finder) {
+void UseStdNumbersCheck::registerMatchers(MatchFinder *const Finder) {
const auto Matches = MatchBuilder{DiffThreshold};
static const auto ConstantMatchers = {
Matches.matchLog2Euler(), Matches.matchLog10Euler(),
@@ -436,9 +436,9 @@ void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
Result.SourceManager->getFileID(Range.getBegin()), "<numbers>");
}
-void UseStdNumbersCheck::registerPPCallbacks(const SourceManager &SM,
- Preprocessor *PP,
- Preprocessor *ModuleExpanderPP) {
+void UseStdNumbersCheck::registerPPCallbacks(
+ const SourceManager &SM, Preprocessor *const PP,
+ Preprocessor *const ModuleExpanderPP) {
IncludeInserter.registerPreprocessor(PP);
}
} // namespace clang::tidy::modernize
>From ce0a7846b1e8d5bf67b3a60246e76218995b2390 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 16 Nov 2023 03:54:49 +0100
Subject: [PATCH 35/44] init DiffThresholdString in the init list
---
clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 513d6468399d3..ed8cc6c6b255d 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -293,8 +293,8 @@ UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name,
: ClangTidyCheck(Name, Context),
IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
- areDiagsSelfContained()) {
- DiffThresholdString = Options.get("DiffThreshold", "0.001");
+ areDiagsSelfContained()),
+ DiffThresholdString{Options.get("DiffThreshold", "0.001")} {
if (DiffThresholdString.getAsDouble(DiffThreshold)) {
configurationDiag(
"Invalid DiffThreshold config value: '%0', expected a double")
>From a3f55401e7acfad14027c117b463d86e2496fab4 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 16 Nov 2023 04:12:23 +0100
Subject: [PATCH 36/44] add comment for isRangeOfCompleteMacro
---
.../clang-tidy/modernize/UseStdNumbersCheck.cpp | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index ed8cc6c6b255d..e25c15d82eaf0 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -387,6 +387,9 @@ void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
const auto Range = Match->getSourceRange();
const auto IsMacro = Range.getBegin().isMacroID();
+
+ // We do not want to emit a diagnostic when we are matching a macro, but the
+ // match inside of the macro does not cover the whole macro.
if (IsMacro && !isRangeOfCompleteMacro(Range, SM, LO)) {
continue;
}
@@ -410,7 +413,7 @@ void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
}
// We may have had no matches with literals, but a match with a pattern that
- // was a subexpression of a macro which was therefore skipped.
+ // was a part of a macro which was therefore skipped.
if (MatchedLiterals.empty()) {
return;
}
@@ -423,6 +426,9 @@ void UseStdNumbersCheck::check(const MatchFinder::MatchResult &Result) {
const auto Range = Node->getSourceRange();
const auto IsMacro = Range.getBegin().isMacroID();
+
+ // We do not want to emit a diagnostic when we are matching a macro, but the
+ // match inside of the macro does not cover the whole macro.
if (IsMacro && !isRangeOfCompleteMacro(Range, SM, LO)) {
return;
}
>From d89b10ab0fc3beec554f6a687e18aadc75447825 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 16 Nov 2023 04:13:37 +0100
Subject: [PATCH 37/44] add explicit tests for macro range check
---
.../checkers/modernize/use-std-numbers.cpp | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 9b292e920e289..c0962fb8e6990 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -32,6 +32,7 @@ void floatSink(float) {}
#define MY_PI 3.1415926
#define INV_SQRT3 1 / bar::sqrt(3)
+#define NOT_INV_SQRT3 1 / bar::sqrt(3) + 1
using my_double = double;
using my_float = float;
@@ -280,6 +281,8 @@ void foo(){
// CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: prefer 'std::numbers::inv_sqrt3' to this macro [modernize-use-std-numbers]
// CHECK-FIXES-ALL: sink(std::numbers::inv_sqrt3);
+ sink(NOT_INV_SQRT3);
+
const auto inv_sqrt3f = .577350269F;
// CHECK-MESSAGES-ALL: :[[@LINE-1]]:29: warning: prefer 'std::numbers::inv_sqrt3_v<float>' to this literal, differs by '1.04e-08' [modernize-use-std-numbers]
// CHECK-FIXES-ALL: const auto inv_sqrt3f = std::numbers::inv_sqrt3_v<float>;
@@ -471,3 +474,16 @@ void foobar(){
void use_foobar() {
foobar<float>();
}
+
+#define BIG_MARCO \
+ struct InvSqrt3 { \
+ template <typename T> static T get() { return 1 / bar::sqrt(3); } \
+ }
+
+BIG_MARCO;
+
+void use_BIG_MACRO() {
+InvSqrt3 f{};
+f.get<float>();
+f.get<double>();
+}
>From 31f7ac29c63662f75543a53dd5454b2796dc2b42 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Fri, 17 Nov 2023 23:47:13 +0100
Subject: [PATCH 38/44] instantiate big test template
---
.../test/clang-tidy/checkers/modernize/use-std-numbers.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index c0962fb8e6990..79ad0ecf5b75a 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -471,8 +471,12 @@ void foobar(){
const T Two = 2;
bar::sqrt(Two);
}
-void use_foobar() {
+void use_templates() {
foobar<float>();
+ foobar<double>();
+
+ baz<float>();
+ baz<double>();
}
#define BIG_MARCO \
>From 030eabfda92bee3ae7e9ea1410f97d6705436d5e Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 23 Nov 2023 20:09:29 +0100
Subject: [PATCH 39/44] fix comment
---
clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index e25c15d82eaf0..17a1d85148f81 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -105,7 +105,7 @@ struct MatchBuilder {
// Used for top-level matchers (i.e. the match that replaces Val with its
// constant).
//
- // E.g. The matcher of `std::numbers::pi` uses this matcher to look to
+ // E.g. The matcher of `std::numbers::pi` uses this matcher to look for
// floatLiterals that have the value of pi.
//
// If the match is for a top-level match, we only care about the literal.
>From bb0b1b33a9fffb5527a502401cf20cb2eba73ee3 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Thu, 23 Nov 2023 20:09:37 +0100
Subject: [PATCH 40/44] rm unless(isInTemplateInstantiation()), because of
IgnoreUnlessSpelledInSource
---
clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 17a1d85148f81..88317948f053d 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -320,7 +320,6 @@ void UseStdNumbersCheck::registerMatchers(MatchFinder *const Finder) {
Finder->addMatcher(
expr(traverse(TK_IgnoreUnlessSpelledInSource,
expr(anyOfExhaustive(ConstantMatchers))),
- unless(isInTemplateInstantiation()),
unless(hasParent(expr(
anyOf(implicitCastExpr(hasImplicitDestinationType(isFloating())),
explicitCastExpr(hasDestinationType(isFloating())))))),
>From 27d2eec25f4b6d98bf4b69bef56ab9fb2a6fd083 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 2 Dec 2023 14:57:39 +0100
Subject: [PATCH 41/44] fix literal in template problem in exchange for not
resolving implicit casts
---
.../modernize/UseStdNumbersCheck.cpp | 18 +++++-------
.../clang-tidy/modernize/UseStdNumbersCheck.h | 3 ++
.../checks/modernize/use-std-numbers.rst | 26 ++++++++---------
.../checkers/modernize/use-std-numbers.cpp | 28 +++++++++----------
4 files changed, 37 insertions(+), 38 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 88317948f053d..450a289eb8f95 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -315,18 +315,14 @@ void UseStdNumbersCheck::registerMatchers(MatchFinder *const Finder) {
Matches.matchPhi(),
};
- // Using 'TK_IgnoreUnlessSpelledInSource' here instead of at the check level
- // to figure out what the type is that the matched constants are used as.
Finder->addMatcher(
- expr(traverse(TK_IgnoreUnlessSpelledInSource,
- expr(anyOfExhaustive(ConstantMatchers))),
- unless(hasParent(expr(
- anyOf(implicitCastExpr(hasImplicitDestinationType(isFloating())),
- explicitCastExpr(hasDestinationType(isFloating())))))),
- hasType(qualType(hasCanonicalTypeUnqualified(
- anyOf(qualType(asString("float")).bind("float"),
- qualType(asString("double")),
- qualType(asString("long double")).bind("long double")))))),
+ expr(
+ anyOfExhaustive(ConstantMatchers),
+ unless(hasParent(explicitCastExpr(hasDestinationType(isFloating())))),
+ hasType(qualType(hasCanonicalTypeUnqualified(
+ anyOf(qualType(asString("float")).bind("float"),
+ qualType(asString("double")),
+ qualType(asString("long double")).bind("long double")))))),
this);
}
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
index ef63987daea84..cab3fe548c49c 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
@@ -37,6 +37,9 @@ class UseStdNumbersCheck : public ClangTidyCheck {
Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
Options.store(Opts, "DiffThreshold", DiffThresholdString);
}
+ std::optional<TraversalKind> getCheckTraversalKind() const override {
+ return TK_IgnoreUnlessSpelledInSource;
+ }
private:
utils::IncludeInserter IncludeInserter;
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
index e51da6575958b..6a6038cb8fab5 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -31,28 +31,28 @@ The following list of constants from the ``numbers`` header are supported:
The list currently includes all constants as of C++20.
-The replacements try to match the type of the inserted constant by how the
-removed expression was used, e.g., switching between ``std::numbers::e`` to
-``std::numbers::e_v<float>`` or ``std::numbers::e_v<long double>``
+The replacements use the type of the matched constant and can remove explicit casts,
+i.e., switching between ``std::numbers::e``, ``std::numbers::e_v<float>`` and ``std::numbers::e_v<long double>``
where appropriate.
.. code-block:: c++
double sqrt(double);
- double log(double);
+ double log2(double);
void sink(auto&&) {}
void floatSink(float);
#define MY_PI 3.1415926
void foo() {
- const double Pi = 3.141592653589; // const double Pi = std::numbers::pi
- const auto Use = Pi / 2; // no match for Pi
- static constexpr double Euler = 2.7182818; // static constexpr double Euler = std::numbers::e;
-
- log2(exp(1)); // std::numbers::log2e;
- log2(Euler); // std::numbers::log2e;
- 1 / sqrt(MY_PI); // std::numbers::inv_sqrtpi;
- sink(MY_PI); // sink(std::numbers::pi);
- floatSink(MY_PI); // floatSink(std::numbers::pi_v<float>);
+ const double Pi = 3.141592653589; // const double Pi = std::numbers::pi
+ const auto Use = Pi / 2; // no match for Pi
+ static constexpr double Euler = 2.7182818; // static constexpr double Euler = std::numbers::e;
+
+ log2(exp(1)); // std::numbers::log2e;
+ log2(Euler); // std::numbers::log2e;
+ 1 / sqrt(MY_PI); // std::numbers::inv_sqrtpi;
+ sink(MY_PI); // sink(std::numbers::pi);
+ floatSink(MY_PI); // floatSink(std::numbers::pi);
+ floatSink(static_cast<float>(MY_PI)); // floatSink(std::numbers::pi_v<float>);
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
index 79ad0ecf5b75a..6c5762da5e2e8 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp
@@ -66,16 +66,16 @@ void foo(){
// CHECK-FIXES-IMPRECISE: static constexpr double Phi2 = std::numbers::phi;
static constexpr double Pi3 = 3.1415926L;
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
- // CHECK-FIXES-ALL: static constexpr double Pi3 = std::numbers::pi;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:35: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr double Pi3 = std::numbers::pi_v<long double>;
static constexpr double Euler3 = 2.7182818L;
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
- // CHECK-FIXES-ALL: static constexpr double Euler3 = std::numbers::e;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e_v<long double>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr double Euler3 = std::numbers::e_v<long double>;
static constexpr double Phi3 = 1.6180339L;
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
- // CHECK-FIXES-ALL: static constexpr double Phi3 = std::numbers::phi;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:36: warning: prefer 'std::numbers::phi_v<long double>' to this literal, differs by '8.87e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr double Phi3 = std::numbers::phi_v<long double>;
static constexpr long double Pi4 = 3.1415926L;
// CHECK-MESSAGES-ALL: :[[@LINE-1]]:40: warning: prefer 'std::numbers::pi_v<long double>' to this literal, differs by '5.36e-08' [modernize-use-std-numbers]
@@ -94,8 +94,8 @@ void foo(){
// CHECK-FIXES-ALL: static constexpr my_double Euler5 = std::numbers::e;
static constexpr my_float Euler6 = 2.7182818;
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:40: warning: prefer 'std::numbers::e_v<float>' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
- // CHECK-FIXES-ALL: static constexpr my_float Euler6 = std::numbers::e_v<float>;
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:40: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: static constexpr my_float Euler6 = std::numbers::e;
static constexpr int NotEuler7 = 2.7182818;
// CHECK-MESSAGES-ALL: :[[@LINE-1]]:38: warning: prefer 'std::numbers::e' to this literal, differs by '2.85e-08' [modernize-use-std-numbers]
@@ -183,16 +183,16 @@ void foo(){
// CHECK-FIXES-ALL: auto log2e = std::numbers::log2e;
floatSink(log2(Euler));
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
- // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' to this formula [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: floatSink(std::numbers::log2e);
floatSink(static_cast<float>(log2(Euler)));
// CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this formula [modernize-use-std-numbers]
// CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
floatSink(1.4426950);
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
- // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: floatSink(std::numbers::log2e);
floatSink(static_cast<float>(1.4426950));
// CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '4.09e-08' [modernize-use-std-numbers]
@@ -217,8 +217,8 @@ void foo(){
// CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
floatSink(static_cast<double>(1.4426950F));
- // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
- // CHECK-FIXES-ALL: floatSink(std::numbers::log2e_v<float>);
+ // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: prefer 'std::numbers::log2e' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
+ // CHECK-FIXES-ALL: floatSink(std::numbers::log2e);
floatSink(static_cast<int>(1.4426950F));
// CHECK-MESSAGES-ALL: :[[@LINE-1]]:32: warning: prefer 'std::numbers::log2e_v<float>' to this literal, differs by '1.93e-08' [modernize-use-std-numbers]
>From e27646aa6e84de078d023f30ba5bc281a4ea3510 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 2 Dec 2023 15:10:18 +0100
Subject: [PATCH 42/44] move def of storeOptions to cpp file
---
.../clang-tidy/modernize/UseStdNumbersCheck.cpp | 5 +++++
clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h | 5 +----
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 450a289eb8f95..7a29c0f1cca8d 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -442,4 +442,9 @@ void UseStdNumbersCheck::registerPPCallbacks(
Preprocessor *const ModuleExpanderPP) {
IncludeInserter.registerPreprocessor(PP);
}
+
+void UseStdNumbersCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+ Options.store(Opts, "DiffThreshold", DiffThresholdString);
+}
} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
index cab3fe548c49c..05fc5ada14b87 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h
@@ -33,10 +33,7 @@ class UseStdNumbersCheck : public ClangTidyCheck {
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
Preprocessor *ModuleExpanderPP) override;
- void storeOptions(ClangTidyOptions::OptionMap &Opts) override {
- Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
- Options.store(Opts, "DiffThreshold", DiffThresholdString);
- }
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
std::optional<TraversalKind> getCheckTraversalKind() const override {
return TK_IgnoreUnlessSpelledInSource;
}
>From ec1a340adbac7dbfaca4191bd5cdbf2b0e1b4968 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Sat, 2 Dec 2023 15:11:13 +0100
Subject: [PATCH 43/44] remove unused include
---
clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
index 7a29c0f1cca8d..1f2b034713ecf 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp
@@ -9,7 +9,6 @@
#include "UseStdNumbersCheck.h"
#include "../ClangTidyDiagnosticConsumer.h"
#include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Stmt.h"
>From 60f4d26b33a0cf2526fc726030cc37a082f04990 Mon Sep 17 00:00:00 2001
From: Julian Schmidt <44101708+5chmidti at users.noreply.github.com>
Date: Mon, 4 Dec 2023 21:35:35 +0100
Subject: [PATCH 44/44] add options to doc
---
.../checks/modernize/use-std-numbers.rst | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
index 6a6038cb8fab5..9eed00bb93915 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst
@@ -56,3 +56,19 @@ where appropriate.
floatSink(MY_PI); // floatSink(std::numbers::pi);
floatSink(static_cast<float>(MY_PI)); // floatSink(std::numbers::pi_v<float>);
}
+
+Options
+-------
+
+.. option:: DiffThreshold
+
+ A floating point value that sets the detection threshold for when literals
+ match a constant.
+ A literal matches a constant if
+ ``abs(literal - constant) < DiffThreshold`` evaluates to true.
+ Default is `0.001`.
+
+.. option:: IncludeStyle
+
+ A string specifying which include-style is used, `llvm` or `google`. Default
+ is `llvm`.
More information about the cfe-commits
mailing list