https://github.com/5chmidti updated https://github.com/llvm/llvm-project/pull/66583
>From 8f5e9e6024b0db8f251625669adbc5d607da83cb Mon Sep 17 00:00:00 2001 From: Julian Schmidt <44101708+5chmi...@users.noreply.github.com> Date: Sat, 16 Sep 2023 16:24:13 +0200 Subject: [PATCH 01/12] [clang-tidy] add modernize-use-std-numbers check This check finds constants and function calls to math functions that can be replaced with c++20's mathematical constants ('numbers' header) and offers fixit-hints. Does not match the use of variables or macros with that value and instead, offers a replacement at the definition of said variables and macros. --- .../clang-tidy/modernize/CMakeLists.txt | 1 + .../modernize/ModernizeTidyModule.cpp | 3 + .../modernize/UseStdNumbersCheck.cpp | 377 ++++++++++++++++++ .../clang-tidy/modernize/UseStdNumbersCheck.h | 37 ++ clang-tools-extra/docs/ReleaseNotes.rst | 6 + .../docs/clang-tidy/checks/list.rst | 3 +- .../checks/modernize/use-std-numbers.rst | 25 ++ .../checkers/modernize/use-std-numbers.cpp | 205 ++++++++++ 8 files changed, 656 insertions(+), 1 deletion(-) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index 717c400c4790330..d82353d74fbd0d4 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -16,6 +16,7 @@ add_clang_library(clangTidyModernizeModule MakeSharedCheck.cpp MakeSmartPtrCheck.cpp MakeUniqueCheck.cpp + UseStdNumbersCheck.cpp ModernizeTidyModule.cpp PassByValueCheck.cpp RawStringLiteralCheck.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 73751cf2705068d..73584e20166f66a 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -18,6 +18,7 @@ #include "MacroToEnumCheck.h" #include "MakeSharedCheck.h" #include "MakeUniqueCheck.h" +#include "UseStdNumbersCheck.h" #include "PassByValueCheck.h" #include "RawStringLiteralCheck.h" #include "RedundantVoidArgCheck.h" @@ -65,6 +66,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck<MacroToEnumCheck>("modernize-macro-to-enum"); CheckFactories.registerCheck<MakeSharedCheck>("modernize-make-shared"); CheckFactories.registerCheck<MakeUniqueCheck>("modernize-make-unique"); + CheckFactories.registerCheck<UseStdNumbersCheck>( + "modernize-use-std-numbers"); CheckFactories.registerCheck<PassByValueCheck>("modernize-pass-by-value"); CheckFactories.registerCheck<UseStdPrintCheck>("modernize-use-std-print"); CheckFactories.registerCheck<RawStringLiteralCheck>( diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp new file mode 100644 index 000000000000000..c23dc6671013bc3 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp @@ -0,0 +1,377 @@ +//===--- UseStdNumbersCheck.cpp - clang_tidy -------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX_License_Identifier: Apache_2.0 WITH LLVM_exception +// +//===----------------------------------------------------------------------===// + +#include "UseStdNumbersCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Expr.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/Type.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/ASTMatchers/ASTMatchersInternal.h" +#include "clang/ASTMatchers/ASTMatchersMacros.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/TokenKinds.h" +#include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Lex/Token.h" +#include "clang/Tooling/Transformer/RewriteRule.h" +#include "clang/Tooling/Transformer/Stencil.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/MathExtras.h" +#include <cstdint> +#include <string> + +namespace { +using namespace clang::ast_matchers; +using clang::ast_matchers::internal::Matcher; +using clang::transformer::addInclude; +using clang::transformer::applyFirst; +using clang::transformer::ASTEdit; +using clang::transformer::cat; +using clang::transformer::changeTo; +using clang::transformer::edit; +using clang::transformer::EditGenerator; +using clang::transformer::flattenVector; +using clang::transformer::RewriteRuleWith; +using llvm::StringRef; + +constexpr double Pi = 3.141592653589793238462643383279502884197169399; +constexpr double Euler = 2.718281828459045235360287471352662497757247093; +constexpr double Phi = 1.618033988749894848204586834365638117720309179; +constexpr double Egamma = 0.577215664901532860606512090082402431042159335; + +constexpr auto DiffThreshold = 0.001; + +AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double, Threshold) { + return std::abs(Node.getValue().convertToDouble() - Value) < Threshold; +} + +// We don't want to match uses of macros, such as +// +// auto PiHalved = MY_PI / 2; +// +// because a project might use defines for math constants. +// Instead, the macro definition is matched and the value is exchanged there. +// Hinting at replacing macro definitions with language constructs is done in +// another check. +AST_MATCHER(clang::Expr, isMathMacro) { return Node.getBeginLoc().isMacroID(); } + +AST_MATCHER_P(clang::QualType, hasUnqualifiedDesugaredType, + Matcher<clang::QualType>, InnerMatcher) { + return InnerMatcher.matches(Node->getCanonicalTypeUnqualified(), Finder, + Builder); +} + +auto matchMathCall(const StringRef FunctionName, + const Matcher<clang::Expr> ArgumentMatcher) { + return callExpr(callee(functionDecl(hasName(FunctionName))), + hasArgument(0, ignoringImplicit(ArgumentMatcher))); +} + +auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) { + return matchMathCall("sqrt", ArgumentMatcher); +} + +// 'MatchDeclRefExprOrMacro' is used to differentiate matching expressions where +// the value of anything used is near 'Val' and matching expressions where we +// only care about the actual literal. +// We don't want top-level matches to match a simple DeclRefExpr/macro that was +// initialized with this value because projects might declare their own +// constants (e.g. namespaced constants or macros) to be used. We don't want to +// flag the use of these variables/constants, but modify the definition of the +// variable or macro. +// +// example: +// const auto e = 2.71828182; // std::numbers::e +// ^^^^^^^^^^ +// match here +// +// auto use = e / 2; +// ^ +// don't match this as a top-level match, this would create noise +// +// auto use2 = log2(e); // std::numbers::log2e +// ^^^^^^^ +// match here, matcher needs to check the initialization +// of e to match log2e +// +// Therefore, all top-level matcher set MatchDeclRefExprOrMacro to false +auto matchFloatValueNear(const double Val, + const bool MatchDeclRefExprOrMacro = true) { + const auto FloatVal = floatLiteral(near(Val, DiffThreshold)); + if (!MatchDeclRefExprOrMacro) { + return expr(unless(isMathMacro()), ignoringImplicit(FloatVal)); + } + + const auto Dref = declRefExpr(to(varDecl( + anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))), + hasInitializer(FloatVal)))); + return expr(ignoringImplicit(anyOf(FloatVal, Dref))); +} + +auto matchValue(const int64_t ValInt) { + const auto Int2 = integerLiteral(equals(ValInt)); + const auto Float2 = matchFloatValueNear(static_cast<double>(ValInt)); + const auto Dref = declRefExpr(to(varDecl( + anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))), + hasInitializer(expr(ignoringImplicit(anyOf(Int2, Float2))))))); + return expr(ignoringImplicit(anyOf(Int2, Float2, Dref))); +} + +auto match1Div(const Matcher<clang::Expr> Match) { + return binaryOperator(hasOperatorName("/"), hasLHS(matchValue(1)), + hasRHS(ignoringImplicit(Match))); +} + +auto matchEuler() { + return expr( + anyOf(matchFloatValueNear(Euler), matchMathCall("exp", matchValue(1)))); +} +auto matchEulerTopLevel() { + return expr(anyOf(matchFloatValueNear(Euler, false), + matchMathCall("exp", matchValue(1)))); +} + +auto matchLog2Euler() { + return expr(anyOf(matchFloatValueNear(llvm::numbers::log2e, false), + matchMathCall("log2", matchEuler()))); +} + +auto matchLog10Euler() { + return expr(anyOf(matchFloatValueNear(llvm::numbers::log10e, false), + matchMathCall("log10", matchEuler()))); +} + +auto matchPi() { return matchFloatValueNear(Pi); } +auto matchPiTopLevel() { return matchFloatValueNear(Pi, false); } + +auto matchEgamma() { return matchFloatValueNear(Egamma, false); } + +auto matchInvPi() { + return expr( + anyOf(matchFloatValueNear(llvm::numbers::inv_pi), match1Div(matchPi()))); +} + +auto matchInvSqrtPi() { + return expr(anyOf(matchFloatValueNear(llvm::numbers::inv_sqrtpi, false), + match1Div(matchSqrt(matchPi())))); +} + +auto matchLn2() { + return expr(anyOf(matchFloatValueNear(llvm::numbers::ln2, false), + matchMathCall("log", ignoringImplicit(matchValue(2))))); +} + +auto machterLn10() { + return expr(anyOf(matchFloatValueNear(llvm::numbers::ln10, false), + matchMathCall("log", ignoringImplicit(matchValue(10))))); +} + +auto matchSqrt2() { + return expr(anyOf(matchFloatValueNear(llvm::numbers::sqrt2, false), + matchSqrt(matchValue(2)))); +} + +auto matchSqrt3() { + return expr(anyOf(matchFloatValueNear(llvm::numbers::sqrt3, false), + matchSqrt(matchValue(3)))); +} + +auto matchInvSqrt3() { + return expr(anyOf(matchFloatValueNear(llvm::numbers::inv_sqrt3, false), + match1Div(matchSqrt(matchValue(3))))); +} + +auto matchPhi() { + const auto PhiFormula = binaryOperator( + hasOperatorName("/"), + hasLHS(parenExpr(has(binaryOperator( + hasOperatorName("+"), hasEitherOperand(matchValue(1)), + hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))), + hasRHS(matchValue(2))); + return expr(anyOf(PhiFormula, matchFloatValueNear(Phi))); +} + +EditGenerator +chainedIfBound(ASTEdit DefaultEdit, + llvm::SmallVector<std::pair<StringRef, ASTEdit>, 2> Edits) { + return [Edits = std::move(Edits), DefaultEdit = std::move(DefaultEdit)]( + const MatchFinder::MatchResult &Result) { + auto &Map = Result.Nodes.getMap(); + for (const auto &[Id, EditOfId] : Edits) { + if (Map.find(Id) != Map.end()) { + return edit(EditOfId)(Result); + } + } + return edit(DefaultEdit)(Result); + }; +} + +RewriteRuleWith<std::string> makeRule(const Matcher<clang::Stmt> Matcher, + const StringRef Constant) { + static const auto AddNumbersInclude = + addInclude("numbers", clang::transformer::IncludeFormat::Angled); + + const auto DefaultEdit = changeTo(cat("std::numbers::", Constant)); + const auto FloatEdit = changeTo(cat("std::numbers::", Constant, "_v<float>")); + const auto LongDoubleEdit = + changeTo(cat("std::numbers::", Constant, "_v<long double>")); + + const auto EditRules = chainedIfBound( + DefaultEdit, {{"float", FloatEdit}, {"long double", LongDoubleEdit}}); + + return makeRule( + expr(Matcher, + hasType(qualType(hasCanonicalType(hasUnqualifiedDesugaredType(anyOf( + qualType(asString("float")).bind("float"), + qualType(asString("double")), + qualType(asString("long double")).bind("long double"))))))), + flattenVector({edit(AddNumbersInclude), EditRules}), + cat("prefer std::numbers math constant")); +} + +/* + List of all math constants + + e + + log2e + + log10e + + pi + + inv_pi + + inv_sqrtpi + + ln2 + + ln10 + + sqrt2 + + sqrt3 + + inv_sqrt3 + + egamma + + phi +*/ + +RewriteRuleWith<std::string> makeRewriteRule() { + return applyFirst({ + makeRule(matchLog2Euler(), "log2e"), + makeRule(matchLog10Euler(), "log10e"), + makeRule(matchEulerTopLevel(), "e"), + makeRule(matchEgamma(), "egamma"), + makeRule(matchInvSqrtPi(), "inv_sqrtpi"), + makeRule(matchInvPi(), "inv_pi"), + makeRule(matchPiTopLevel(), "pi"), + makeRule(matchLn2(), "ln2"), + makeRule(machterLn10(), "ln10"), + makeRule(matchSqrt2(), "sqrt2"), + makeRule(matchInvSqrt3(), "inv_sqrt3"), + makeRule(matchSqrt3(), "sqrt3"), + makeRule(matchPhi(), "phi"), + }); +} + +class MathConstantMacroCallback : public clang::PPCallbacks { +public: + explicit MathConstantMacroCallback( + clang::tidy::modernize::UseStdNumbersCheck *Check) + : Check{Check} {}; + + void MacroDefined(const clang::Token & /*MacroNameTok*/, + const clang::MacroDirective *MD) override { + for (const auto &Tok : MD->getDefinition().getMacroInfo()->tokens()) { + if (!Tok.is(clang::tok::numeric_constant)) { + continue; + } + + const auto Definition = + llvm::StringRef{Tok.getLiteralData(), Tok.getLength()}; + double Value{}; + Definition.getAsDouble(Value); + + const auto IsNear = [](const auto Lhs, const auto Rhs) { + return std::abs(Lhs - Rhs) < DiffThreshold; + }; + + if (IsNear(Value, llvm::numbers::log2e)) { + reportDiag(Tok, "std::numbers::log2e"); + return; + } + if (IsNear(Value, llvm::numbers::log10e)) { + reportDiag(Tok, "std::numbers::log10e"); + return; + } + if (IsNear(Value, llvm::numbers::e)) { + reportDiag(Tok, "std::numbers::e"); + return; + } + if (IsNear(Value, llvm::numbers::egamma)) { + reportDiag(Tok, "std::numbers::egamma"); + return; + } + if (IsNear(Value, llvm::numbers::inv_sqrtpi)) { + reportDiag(Tok, "std::numbers::inv_sqrtpi"); + return; + } + if (IsNear(Value, llvm::numbers::inv_pi)) { + reportDiag(Tok, "std::numbers::inv_pi"); + return; + } + if (IsNear(Value, llvm::numbers::pi)) { + reportDiag(Tok, "std::numbers::pi"); + return; + } + if (IsNear(Value, llvm::numbers::ln2)) { + reportDiag(Tok, "std::numbers::ln2"); + return; + } + if (IsNear(Value, llvm::numbers::ln10)) { + reportDiag(Tok, "std::numbers::ln10"); + return; + } + if (IsNear(Value, llvm::numbers::sqrt2)) { + reportDiag(Tok, "std::numbers::sqrt2"); + return; + } + if (IsNear(Value, llvm::numbers::inv_sqrt3)) { + reportDiag(Tok, "std::numbers::inv_sqrt3"); + return; + } + if (IsNear(Value, llvm::numbers::sqrt3)) { + reportDiag(Tok, "std::numbers::sqrt3"); + return; + } + if (IsNear(Value, llvm::numbers::phi)) { + reportDiag(Tok, "std::numbers::phi"); + return; + } + } + } + +private: + void reportDiag(const clang::Token &Tok, const llvm::StringRef Constant) { + Check->diag(Tok.getLocation(), "prefer math constant") + << clang::FixItHint::CreateReplacement( + clang::SourceRange(Tok.getLocation(), Tok.getLastLoc()), + Constant); + } + + clang::tidy::modernize::UseStdNumbersCheck *Check{}; +}; +} // namespace + +namespace clang::tidy::modernize { +UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name, + ClangTidyContext *const Context) + : TransformerClangTidyCheck(Name, Context) { + setRule(makeRewriteRule()); +} + +void UseStdNumbersCheck::registerPPCallbacks(const SourceManager &SM, + Preprocessor *PP, + Preprocessor *ModuleExpanderPP) { + utils::TransformerClangTidyCheck::registerPPCallbacks(SM, PP, + ModuleExpanderPP); + PP->addPPCallbacks(std::make_unique<MathConstantMacroCallback>(this)); +} +} // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h new file mode 100644 index 000000000000000..5598d533a3ea716 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h @@ -0,0 +1,37 @@ +//===--- UseStdNumbersCheck.h - clang-tidy ----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDNUMBERSCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDNUMBERSCHECK_H + +#include "../utils/TransformerClangTidyCheck.h" + +namespace clang::tidy::modernize { + +/// Finds constants and function calls to math functions that can be replaced +/// with c++20's mathematical constants ('numbers' header). Does not match the +/// use of variables or macros with that value and instead offers a replacement +/// at the definition of said variables and macros. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-numbers.html +class UseStdNumbersCheck : public utils::TransformerClangTidyCheck { +public: + UseStdNumbersCheck(StringRef Name, ClangTidyContext *Context); + + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus20; + } + + void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, + Preprocessor *ModuleExpanderPP) override; +}; + +} // namespace clang::tidy::modernize + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USESTDNUMBERSCHECK_H diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 6d6f51998a01e57..02efc22a7fe164e 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -163,6 +163,12 @@ New checks Flags coroutines that suspend while a lock guard is in scope at the suspension point. +- New :doc:`modernize-use-std-numbers + <clang-tidy/checks/modernize/use-std-numbers>` check. + + Finds constants and function calls to math functions that can be replaced + with c++20's mathematical constants ('numbers' header). + - New :doc:`modernize-use-constraints <clang-tidy/checks/modernize/use-constraints>` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 1baabceea06ef48..ae1d541e40387a1 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -82,7 +82,7 @@ Clang-Tidy Checks :doc:`bugprone-bad-signal-to-kill-thread <bugprone/bad-signal-to-kill-thread>`, :doc:`bugprone-bool-pointer-implicit-conversion <bugprone/bool-pointer-implicit-conversion>`, "Yes" :doc:`bugprone-branch-clone <bugprone/branch-clone>`, - :doc:`bugprone-compare-pointer-to-member-virtual-function <bugprone/compare-pointer-to-member-virtual-function>`, "Yes" + :doc:`bugprone-compare-pointer-to-member-virtual-function <bugprone/compare-pointer-to-member-virtual-function>`, :doc:`bugprone-copy-constructor-init <bugprone/copy-constructor-init>`, "Yes" :doc:`bugprone-dangling-handle <bugprone/dangling-handle>`, :doc:`bugprone-dynamic-static-initializers <bugprone/dynamic-static-initializers>`, @@ -290,6 +290,7 @@ Clang-Tidy Checks :doc:`modernize-use-noexcept <modernize/use-noexcept>`, "Yes" :doc:`modernize-use-nullptr <modernize/use-nullptr>`, "Yes" :doc:`modernize-use-override <modernize/use-override>`, "Yes" + :doc:`modernize-use-std-numbers <modernize/use-std-numbers>`, "Yes" :doc:`modernize-use-std-print <modernize/use-std-print>`, "Yes" :doc:`modernize-use-trailing-return-type <modernize/use-trailing-return-type>`, "Yes" :doc:`modernize-use-transparent-functors <modernize/use-transparent-functors>`, "Yes" diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst new file mode 100644 index 000000000000000..7911f2f7f857b95 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst @@ -0,0 +1,25 @@ +.. title:: clang-tidy - modernize-use-std-numbers + +modernize-use-std-numbers +========================= + +This check finds constants and function calls to math functions that can be replaced +with c++20's mathematical constants ('numbers' header) and offers fixit-hints. +Does not match the use of variables or macros with that value and instead, offers a replacement +at the definition of said variables and macros. + +.. code-block:: c++ + double sqrt(double); + double log(double); + + #define MY_PI 3.1415926 // #define MY_PI std::numbers::pi + + void foo() { + const double Pi = 3.141592653589; // const double Pi = std::numbers::pi + const auto Use = Pi / 2; // no match for Pi + static constexpr double Euler = 2.7182818; // static constexpr double Euler = std::numbers::e; + + log2(exp(1)); // std::numbers::log2e; + log2(Euler); // std::numbers::log2e; + 1 / sqrt(MY_PI); // std::numbers::inv_sqrtpi; + } diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp new file mode 100644 index 000000000000000..2ba0525f38306df --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp @@ -0,0 +1,205 @@ +// RUN: %check_clang_tidy -std=c++20 %s modernize-use-std-numbers %t + +// CHECK-FIXES: #include <numbers> + +namespace bar { + double sqrt(double Arg); + float sqrt(float Arg); + template <typename T> + auto sqrt(T val) { return sqrt(static_cast<double>(val)); } + + static constexpr double e = 2.718281828459045235360287471352662497757247093; + // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr double e = std::numbers::e; +} + +double exp(double Arg); +double log(double Arg); +double log2(double Arg); +double log10(double Arg); + +template<typename T> +void sink(T&&) { } + +#define MY_PI 3.1415926 +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer math constant [modernize-use-std-numbers] +// CHECK-FIXES: #define MY_PI std::numbers::pi +#define MY_PI2 static_cast<float>(3.1415926) +// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers] +// CHECK-FIXES: #define MY_PI2 static_cast<float>(std::numbers::pi) + +#define INV_SQRT3 1 / bar::sqrt(3) + +void foo(){ + static constexpr double Pi = 3.1415926; + // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr double Pi = std::numbers::pi; + + static constexpr double Euler = 2.7182818; + // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr double Euler = std::numbers::e; + + static constexpr double Phi = 1.6180339; + // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr double Phi = std::numbers::phi; + + static constexpr double PiCopy = Pi; + static constexpr double PiDefine = MY_PI; + + // not close enough to match value (DiffThreshold) + static constexpr double Pi2 = 3.14; + static constexpr double Euler2 = 2.71; + static constexpr double Phi2 = 1.61; + + static constexpr double Pi3 = 3.1415926L; + // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr double Pi3 = std::numbers::pi; + + static constexpr double Euler3 = 2.7182818L; + // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr double Euler3 = std::numbers::e; + + static constexpr double Phi3 = 1.6180339L; + // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr double Phi3 = std::numbers::phi; + + static constexpr long double Pi4 = 3.1415926L; + // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr long double Pi4 = std::numbers::pi_v<long double>; + + static constexpr long double Euler4 = 2.7182818L; + // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr long double Euler4 = std::numbers::e_v<long double>; + + static constexpr long double Phi4 = 1.6180339L; + // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>; + + using my_float = const float; + static constexpr my_float Actually2MyFloat = 2; + bar::sqrt(Actually2MyFloat); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::sqrt2_v<float>; + + constexpr static auto One = 1; + constexpr static auto Two = 2; + + bar::sqrt(2); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::sqrt2; + + bar::sqrt(Two); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::sqrt2; + + bar::sqrt(2.0); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::sqrt2; + + auto Not2 = 2; + Not2 = 42; + bar::sqrt(Not2); + + const auto Actually2 = 2; + bar::sqrt(Actually2); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::sqrt2; + + exp(1); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::e; + + exp(One); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::e; + + exp(1.00000000000001); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::e; + + log2(exp(1)); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::log2e; + + log2(Euler); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::log2e; + + log2(bar::e); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::log2e; + + auto log2e = 1.4426950; + // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: auto log2e = std::numbers::log2e; + + log10(exp(1)); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::log10e; + + log10(Euler); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::log10e; + + log10(bar::e); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::log10e; + + auto log10e = .434294; + // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: auto log10e = std::numbers::log10e; + + auto egamma = 0.5772156 * 42; + // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: auto egamma = std::numbers::egamma * 42; + + sink(1 / Pi); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: sink(std::numbers::inv_pi); + + sink(1 / bar::sqrt(Pi)); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: sink(std::numbers::inv_sqrtpi); + + sink(1 / bar::sqrt(MY_PI)); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: sink(std::numbers::inv_sqrtpi); + + + log(2); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::ln2; + + log(10); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::ln10; + + bar::sqrt(2); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::sqrt2; + + sink(1 / bar::sqrt(3)); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: sink(std::numbers::inv_sqrt3); + + bar::sqrt(3); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::sqrt3; + + auto phi = 1.6180339; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: auto phi = std::numbers::phi; + + sink((42 + bar::sqrt(5)) / 2); + + sink((1 + bar::sqrt(5)) / 2); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: sink(std::numbers::phi); + + sink((bar::sqrt(5.0F) + 1) / 2); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-FIXES: sink(std::numbers::phi_v<float>); +} >From c52e8a625e5b098054ce24a5b9aa309ce4a290e8 Mon Sep 17 00:00:00 2001 From: Julian Schmidt <44101708+5chmi...@users.noreply.github.com> Date: Sat, 16 Sep 2023 21:13:56 +0200 Subject: [PATCH 02/12] add "Yes" back to list.rst that mysteriously disappeared for unrelated check --- clang-tools-extra/docs/clang-tidy/checks/list.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index ae1d541e40387a1..dd90cd8ae92b424 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -82,7 +82,7 @@ Clang-Tidy Checks :doc:`bugprone-bad-signal-to-kill-thread <bugprone/bad-signal-to-kill-thread>`, :doc:`bugprone-bool-pointer-implicit-conversion <bugprone/bool-pointer-implicit-conversion>`, "Yes" :doc:`bugprone-branch-clone <bugprone/branch-clone>`, - :doc:`bugprone-compare-pointer-to-member-virtual-function <bugprone/compare-pointer-to-member-virtual-function>`, + :doc:`bugprone-compare-pointer-to-member-virtual-function <bugprone/compare-pointer-to-member-virtual-function>`, "Yes" :doc:`bugprone-copy-constructor-init <bugprone/copy-constructor-init>`, "Yes" :doc:`bugprone-dangling-handle <bugprone/dangling-handle>`, :doc:`bugprone-dynamic-static-initializers <bugprone/dynamic-static-initializers>`, >From 3fd29e448efb12d4d06a930bfcc045990b8ad02f Mon Sep 17 00:00:00 2001 From: Julian Schmidt <44101708+5chmi...@users.noreply.github.com> Date: Sat, 16 Sep 2023 21:19:10 +0200 Subject: [PATCH 03/12] fix lexicographical ordering in some places after rename --- clang-tools-extra/clang-tidy/modernize/CMakeLists.txt | 2 +- .../clang-tidy/modernize/ModernizeTidyModule.cpp | 2 +- clang-tools-extra/docs/ReleaseNotes.rst | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index d82353d74fbd0d4..b254d340c4e854a 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -16,7 +16,6 @@ add_clang_library(clangTidyModernizeModule MakeSharedCheck.cpp MakeSmartPtrCheck.cpp MakeUniqueCheck.cpp - UseStdNumbersCheck.cpp ModernizeTidyModule.cpp PassByValueCheck.cpp RawStringLiteralCheck.cpp @@ -39,6 +38,7 @@ add_clang_library(clangTidyModernizeModule UseNoexceptCheck.cpp UseNullptrCheck.cpp UseOverrideCheck.cpp + UseStdNumbersCheck.cpp UseStdPrintCheck.cpp UseTrailingReturnTypeCheck.cpp UseTransparentFunctorsCheck.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 73584e20166f66a..4f33db5b741a7ef 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -18,7 +18,6 @@ #include "MacroToEnumCheck.h" #include "MakeSharedCheck.h" #include "MakeUniqueCheck.h" -#include "UseStdNumbersCheck.h" #include "PassByValueCheck.h" #include "RawStringLiteralCheck.h" #include "RedundantVoidArgCheck.h" @@ -40,6 +39,7 @@ #include "UseNoexceptCheck.h" #include "UseNullptrCheck.h" #include "UseOverrideCheck.h" +#include "UseStdNumbersCheck.h" #include "UseStdPrintCheck.h" #include "UseTrailingReturnTypeCheck.h" #include "UseTransparentFunctorsCheck.h" diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 02efc22a7fe164e..9fabdda3619ed82 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -163,17 +163,17 @@ New checks Flags coroutines that suspend while a lock guard is in scope at the suspension point. +- New :doc:`modernize-use-constraints + <clang-tidy/checks/modernize/use-constraints>` check. + + Replace ``enable_if`` with C++20 requires clauses. + - New :doc:`modernize-use-std-numbers <clang-tidy/checks/modernize/use-std-numbers>` check. Finds constants and function calls to math functions that can be replaced with c++20's mathematical constants ('numbers' header). -- New :doc:`modernize-use-constraints - <clang-tidy/checks/modernize/use-constraints>` check. - - Replace ``enable_if`` with C++20 requires clauses. - - New :doc:`performance-enum-size <clang-tidy/checks/performance/enum-size>` check. >From 5603bead129dc3cd784574acc9a6c0832fa8e719 Mon Sep 17 00:00:00 2001 From: Julian Schmidt <44101708+5chmi...@users.noreply.github.com> Date: Sun, 17 Sep 2023 11:44:58 +0200 Subject: [PATCH 04/12] address comments - changed ReleaseNotes and first sentence of the check documentation by removing parentheses around the numbers header and noted that fix-it hints are emitted --- clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 2 +- clang-tools-extra/docs/ReleaseNotes.rst | 3 ++- .../docs/clang-tidy/checks/modernize/use-std-numbers.rst | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp index c23dc6671013bc3..f4bcfb903ad080b 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp @@ -1,4 +1,4 @@ -//===--- UseStdNumbersCheck.cpp - clang_tidy -------------------------===// +//===--- UseStdNumbersCheck.cpp - clang_tidy ------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 9fabdda3619ed82..bb75ecaf188f76a 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -172,7 +172,8 @@ New checks <clang-tidy/checks/modernize/use-std-numbers>` check. Finds constants and function calls to math functions that can be replaced - with c++20's mathematical constants ('numbers' header). + with c++20's mathematical constants from the ``numbers`` header and + offers fix-it hints. - New :doc:`performance-enum-size <clang-tidy/checks/performance/enum-size>` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst index 7911f2f7f857b95..ec443123334f559 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst @@ -3,8 +3,8 @@ modernize-use-std-numbers ========================= -This check finds constants and function calls to math functions that can be replaced -with c++20's mathematical constants ('numbers' header) and offers fixit-hints. +Finds constants and function calls to math functions that can be replaced +with c++20's mathematical constants from the ``numbers`` header and offers fix-it hints. Does not match the use of variables or macros with that value and instead, offers a replacement at the definition of said variables and macros. >From 4583f5fe62873cac03e299f80d2db9943f56fd30 Mon Sep 17 00:00:00 2001 From: Julian Schmidt <44101708+5chmi...@users.noreply.github.com> Date: Sun, 17 Sep 2023 18:54:56 +0200 Subject: [PATCH 05/12] update descriptions slightly - update check description in header to reflect release notes description - add comma --- .../clang-tidy/modernize/UseStdNumbersCheck.h | 7 ++++--- .../docs/clang-tidy/checks/modernize/use-std-numbers.rst | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h index 5598d533a3ea716..9fc98a1892b2935 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.h @@ -14,9 +14,10 @@ namespace clang::tidy::modernize { /// Finds constants and function calls to math functions that can be replaced -/// with c++20's mathematical constants ('numbers' header). Does not match the -/// use of variables or macros with that value and instead offers a replacement -/// at the definition of said variables and macros. +/// with c++20's mathematical constants from the ``numbers`` header and +/// offers fix-it hints. +/// Does not match the use of variables or macros with that value, and instead, +/// offers a replacement at the definition of said variables and macros. /// /// For the user-facing documentation see: /// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-std-numbers.html diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst index ec443123334f559..613db21435177cc 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-std-numbers.rst @@ -5,7 +5,7 @@ modernize-use-std-numbers Finds constants and function calls to math functions that can be replaced with c++20's mathematical constants from the ``numbers`` header and offers fix-it hints. -Does not match the use of variables or macros with that value and instead, offers a replacement +Does not match the use of variables or macros with that value, and instead, offers a replacement at the definition of said variables and macros. .. code-block:: c++ >From 308099afa1b602b23df7f3287e4e0ca9561824ca Mon Sep 17 00:00:00 2001 From: Julian Schmidt <44101708+5chmi...@users.noreply.github.com> Date: Mon, 18 Sep 2023 22:15:42 +0200 Subject: [PATCH 06/12] fixup update of warning message --- .../modernize/UseStdNumbersCheck.cpp | 2 +- .../checkers/modernize/use-std-numbers.cpp | 86 +++++++++---------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp index f4bcfb903ad080b..bce0ab2117a48e0 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp @@ -350,7 +350,7 @@ class MathConstantMacroCallback : public clang::PPCallbacks { private: void reportDiag(const clang::Token &Tok, const llvm::StringRef Constant) { - Check->diag(Tok.getLocation(), "prefer math constant") + Check->diag(Tok.getLocation(), "prefer std::numbers math constant") << clang::FixItHint::CreateReplacement( clang::SourceRange(Tok.getLocation(), Tok.getLastLoc()), Constant); diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp index 2ba0525f38306df..bc9ecdaf8bc924d 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp @@ -9,7 +9,7 @@ namespace bar { auto sqrt(T val) { return sqrt(static_cast<double>(val)); } static constexpr double e = 2.718281828459045235360287471352662497757247093; - // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: static constexpr double e = std::numbers::e; } @@ -22,25 +22,25 @@ template<typename T> void sink(T&&) { } #define MY_PI 3.1415926 -// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer math constant [modernize-use-std-numbers] +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: #define MY_PI std::numbers::pi #define MY_PI2 static_cast<float>(3.1415926) -// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers] +// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: #define MY_PI2 static_cast<float>(std::numbers::pi) #define INV_SQRT3 1 / bar::sqrt(3) void foo(){ static constexpr double Pi = 3.1415926; - // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: static constexpr double Pi = std::numbers::pi; static constexpr double Euler = 2.7182818; - // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: static constexpr double Euler = std::numbers::e; static constexpr double Phi = 1.6180339; - // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: static constexpr double Phi = std::numbers::phi; static constexpr double PiCopy = Pi; @@ -52,48 +52,48 @@ void foo(){ static constexpr double Phi2 = 1.61; static constexpr double Pi3 = 3.1415926L; - // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: static constexpr double Pi3 = std::numbers::pi; static constexpr double Euler3 = 2.7182818L; - // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: static constexpr double Euler3 = std::numbers::e; static constexpr double Phi3 = 1.6180339L; - // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: static constexpr double Phi3 = std::numbers::phi; static constexpr long double Pi4 = 3.1415926L; - // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:40: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: static constexpr long double Pi4 = std::numbers::pi_v<long double>; static constexpr long double Euler4 = 2.7182818L; - // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: static constexpr long double Euler4 = std::numbers::e_v<long double>; static constexpr long double Phi4 = 1.6180339L; - // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: static constexpr long double Phi4 = std::numbers::phi_v<long double>; using my_float = const float; static constexpr my_float Actually2MyFloat = 2; bar::sqrt(Actually2MyFloat); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::sqrt2_v<float>; constexpr static auto One = 1; constexpr static auto Two = 2; bar::sqrt(2); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::sqrt2; bar::sqrt(Two); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::sqrt2; bar::sqrt(2.0); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::sqrt2; auto Not2 = 2; @@ -102,104 +102,104 @@ void foo(){ const auto Actually2 = 2; bar::sqrt(Actually2); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::sqrt2; exp(1); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::e; exp(One); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::e; exp(1.00000000000001); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::e; log2(exp(1)); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] - // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::log2e; log2(Euler); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::log2e; log2(bar::e); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::log2e; auto log2e = 1.4426950; - // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: auto log2e = std::numbers::log2e; log10(exp(1)); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] - // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::log10e; log10(Euler); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::log10e; log10(bar::e); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::log10e; auto log10e = .434294; - // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: auto log10e = std::numbers::log10e; auto egamma = 0.5772156 * 42; - // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: auto egamma = std::numbers::egamma * 42; sink(1 / Pi); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: sink(std::numbers::inv_pi); sink(1 / bar::sqrt(Pi)); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: sink(std::numbers::inv_sqrtpi); sink(1 / bar::sqrt(MY_PI)); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: sink(std::numbers::inv_sqrtpi); log(2); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::ln2; log(10); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::ln10; bar::sqrt(2); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::sqrt2; sink(1 / bar::sqrt(3)); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers] - // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: sink(std::numbers::inv_sqrt3); bar::sqrt(3); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: std::numbers::sqrt3; auto phi = 1.6180339; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: auto phi = std::numbers::phi; sink((42 + bar::sqrt(5)) / 2); sink((1 + bar::sqrt(5)) / 2); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: sink(std::numbers::phi); sink((bar::sqrt(5.0F) + 1) / 2); - // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: sink(std::numbers::phi_v<float>); } >From 4cb2c2702116f533e4332a0d7711f9b83ae68ae4 Mon Sep 17 00:00:00 2001 From: Julian Schmidt <44101708+5chmi...@users.noreply.github.com> Date: Mon, 25 Sep 2023 12:42:21 +0200 Subject: [PATCH 07/12] rename isMathMacro to isMacro --- clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp index bce0ab2117a48e0..7fa4d00d4552044 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp @@ -60,7 +60,7 @@ AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double, Threshold) { // Instead, the macro definition is matched and the value is exchanged there. // Hinting at replacing macro definitions with language constructs is done in // another check. -AST_MATCHER(clang::Expr, isMathMacro) { return Node.getBeginLoc().isMacroID(); } +AST_MATCHER(clang::Expr, isMacro) { return Node.getBeginLoc().isMacroID(); } AST_MATCHER_P(clang::QualType, hasUnqualifiedDesugaredType, Matcher<clang::QualType>, InnerMatcher) { @@ -106,7 +106,7 @@ auto matchFloatValueNear(const double Val, const bool MatchDeclRefExprOrMacro = true) { const auto FloatVal = floatLiteral(near(Val, DiffThreshold)); if (!MatchDeclRefExprOrMacro) { - return expr(unless(isMathMacro()), ignoringImplicit(FloatVal)); + return expr(unless(isMacro()), ignoringImplicit(FloatVal)); } const auto Dref = declRefExpr(to(varDecl( >From d4815d8fbda40d628cbb6d725239fbb2f267419e Mon Sep 17 00:00:00 2001 From: Julian Schmidt <44101708+5chmi...@users.noreply.github.com> Date: Mon, 25 Sep 2023 13:14:53 +0200 Subject: [PATCH 08/12] add tests for uses in templates - dont match in template instantiations --- .../modernize/UseStdNumbersCheck.cpp | 2 +- .../checkers/modernize/use-std-numbers.cpp | 160 ++++++++++++++++++ 2 files changed, 161 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp index 7fa4d00d4552044..db92a1f50b7bc25 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp @@ -227,7 +227,7 @@ RewriteRuleWith<std::string> makeRule(const Matcher<clang::Stmt> Matcher, DefaultEdit, {{"float", FloatEdit}, {"long double", LongDoubleEdit}}); return makeRule( - expr(Matcher, + expr(Matcher, unless(isInTemplateInstantiation()), hasType(qualType(hasCanonicalType(hasUnqualifiedDesugaredType(anyOf( qualType(asString("float")).bind("float"), qualType(asString("double")), diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp index bc9ecdaf8bc924d..8914ffc1e05f426 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-numbers.cpp @@ -203,3 +203,163 @@ void foo(){ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers] // CHECK-FIXES: sink(std::numbers::phi_v<float>); } + + + +template <typename T> +void baz(){ + static constexpr T Pi = 3.1415926; + // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr T Pi = std::numbers::pi; + + static constexpr T Euler = 2.7182818; + // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr T Euler = std::numbers::e; + + static constexpr T Phi = 1.6180339; + // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr T Phi = std::numbers::phi; + + static constexpr T PiCopy = Pi; + static constexpr T PiDefine = MY_PI; + + // not close enough to match value (DiffThreshold) + static constexpr T Pi2 = 3.14; + static constexpr T Euler2 = 2.71; + static constexpr T Phi2 = 1.61; + + static constexpr T Pi3 = 3.1415926L; + // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr T Pi3 = std::numbers::pi_v<long double>; + + static constexpr T Euler3 = 2.7182818L; + // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr T Euler3 = std::numbers::e_v<long double>; + + static constexpr T Phi3 = 1.6180339L; + // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: static constexpr T Phi3 = std::numbers::phi_v<long double>; + + using my_float = const float; + static constexpr my_float Actually2MyFloat = 2; + bar::sqrt(Actually2MyFloat); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::sqrt2_v<float>; + + constexpr static T One = 1; + constexpr static T Two = 2; + + bar::sqrt(2); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::sqrt2; + + bar::sqrt(Two); + + bar::sqrt(2.0); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::sqrt2; + + T Not2 = 2; + Not2 = 42; + bar::sqrt(Not2); + + const T Actually2 = 2; + bar::sqrt(Actually2); + + exp(1); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::e; + + exp(One); + + exp(1.00000000000001); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::e; + + log2(exp(1)); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::log2e; + + log2(Euler); + + log2(bar::e); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::log2e; + + T log2e = 1.4426950; + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: T log2e = std::numbers::log2e; + + log10(exp(1)); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::log10e; + + log10(Euler); + + log10(bar::e); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::log10e; + + T log10e = .434294; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: T log10e = std::numbers::log10e; + + T egamma = 0.5772156 * 42; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: T egamma = std::numbers::egamma * 42; + + sink(1 / Pi); + + sink(1 / bar::sqrt(Pi)); + + sink(1 / bar::sqrt(MY_PI)); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: sink(std::numbers::inv_sqrtpi); + + + log(2); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::ln2; + + log(10); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::ln10; + + bar::sqrt(2); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::sqrt2; + + sink(1 / bar::sqrt(3)); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: sink(std::numbers::inv_sqrt3); + + bar::sqrt(3); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: std::numbers::sqrt3; + + T phi = 1.6180339; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: T phi = std::numbers::phi; + + sink((42 + bar::sqrt(5)) / 2); + + sink((1 + bar::sqrt(5)) / 2); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: sink(std::numbers::phi); + + sink((bar::sqrt(5.0F) + 1) / 2); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer std::numbers math constant [modernize-use-std-numbers] + // CHECK-FIXES: sink(std::numbers::phi_v<float>); +} + +template <typename T> +void foobar(){ + const T Two = 2; + bar::sqrt(Two); +} +void use_foobar() { + foobar<float>(); +} >From a7e040d72af575597b7f0f5b1b2e311fc1da5720 Mon Sep 17 00:00:00 2001 From: Julian Schmidt <44101708+5chmi...@users.noreply.github.com> Date: Mon, 25 Sep 2023 13:15:04 +0200 Subject: [PATCH 09/12] fix matcher names --- .../clang-tidy/modernize/UseStdNumbersCheck.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp index db92a1f50b7bc25..8b3fa976b74d451 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp @@ -104,24 +104,24 @@ auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) { // Therefore, all top-level matcher set MatchDeclRefExprOrMacro to false auto matchFloatValueNear(const double Val, const bool MatchDeclRefExprOrMacro = true) { - const auto FloatVal = floatLiteral(near(Val, DiffThreshold)); + const auto Float = floatLiteral(near(Val, DiffThreshold)); if (!MatchDeclRefExprOrMacro) { - return expr(unless(isMacro()), ignoringImplicit(FloatVal)); + return expr(unless(isMacro()), ignoringImplicit(Float)); } const auto Dref = declRefExpr(to(varDecl( anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))), - hasInitializer(FloatVal)))); - return expr(ignoringImplicit(anyOf(FloatVal, Dref))); + hasInitializer(Float)))); + return expr(ignoringImplicit(anyOf(Float, Dref))); } auto matchValue(const int64_t ValInt) { - const auto Int2 = integerLiteral(equals(ValInt)); - const auto Float2 = matchFloatValueNear(static_cast<double>(ValInt)); + const auto Int = integerLiteral(equals(ValInt)); + const auto Float = matchFloatValueNear(static_cast<double>(ValInt)); const auto Dref = declRefExpr(to(varDecl( anyOf(isConstexpr(), varDecl(hasType(qualType(isConstQualified())))), - hasInitializer(expr(ignoringImplicit(anyOf(Int2, Float2))))))); - return expr(ignoringImplicit(anyOf(Int2, Float2, Dref))); + hasInitializer(expr(ignoringImplicit(anyOf(Int, Float))))))); + return expr(ignoringImplicit(anyOf(Int, Float, Dref))); } auto match1Div(const Matcher<clang::Expr> Match) { >From 09e9cf59cd2b5987b0ff1a3beb5813db709db03e Mon Sep 17 00:00:00 2001 From: Julian Schmidt <44101708+5chmi...@users.noreply.github.com> Date: Sat, 7 Oct 2023 17:58:15 +0200 Subject: [PATCH 10/12] fix name of custom matcher hasCanonicalTypeUnqualified --- clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp index 8b3fa976b74d451..6fe31c43115ab5f 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp @@ -62,7 +62,7 @@ AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double, Threshold) { // another check. AST_MATCHER(clang::Expr, isMacro) { return Node.getBeginLoc().isMacroID(); } -AST_MATCHER_P(clang::QualType, hasUnqualifiedDesugaredType, +AST_MATCHER_P(clang::QualType, hasCanonicalTypeUnqualified, Matcher<clang::QualType>, InnerMatcher) { return InnerMatcher.matches(Node->getCanonicalTypeUnqualified(), Finder, Builder); @@ -228,7 +228,7 @@ RewriteRuleWith<std::string> makeRule(const Matcher<clang::Stmt> Matcher, return makeRule( expr(Matcher, unless(isInTemplateInstantiation()), - hasType(qualType(hasCanonicalType(hasUnqualifiedDesugaredType(anyOf( + hasType(qualType(hasCanonicalType(hasCanonicalTypeUnqualified(anyOf( qualType(asString("float")).bind("float"), qualType(asString("double")), qualType(asString("long double")).bind("long double"))))))), >From 7e9e7333571b0fb9e01108182a11c9818ebc31d3 Mon Sep 17 00:00:00 2001 From: Julian Schmidt <44101708+5chmi...@users.noreply.github.com> Date: Sat, 7 Oct 2023 18:01:50 +0200 Subject: [PATCH 11/12] remove custom constants in favor of using llvm::numbers for all --- .../modernize/UseStdNumbersCheck.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp index 6fe31c43115ab5f..799b5cc2aaa818e 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp @@ -41,11 +41,6 @@ using clang::transformer::flattenVector; using clang::transformer::RewriteRuleWith; using llvm::StringRef; -constexpr double Pi = 3.141592653589793238462643383279502884197169399; -constexpr double Euler = 2.718281828459045235360287471352662497757247093; -constexpr double Phi = 1.618033988749894848204586834365638117720309179; -constexpr double Egamma = 0.577215664901532860606512090082402431042159335; - constexpr auto DiffThreshold = 0.001; AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double, Threshold) { @@ -130,11 +125,11 @@ auto match1Div(const Matcher<clang::Expr> Match) { } auto matchEuler() { - return expr( - anyOf(matchFloatValueNear(Euler), matchMathCall("exp", matchValue(1)))); + return expr(anyOf(matchFloatValueNear(llvm::numbers::e), + matchMathCall("exp", matchValue(1)))); } auto matchEulerTopLevel() { - return expr(anyOf(matchFloatValueNear(Euler, false), + return expr(anyOf(matchFloatValueNear(llvm::numbers::e, false), matchMathCall("exp", matchValue(1)))); } @@ -148,10 +143,10 @@ auto matchLog10Euler() { matchMathCall("log10", matchEuler()))); } -auto matchPi() { return matchFloatValueNear(Pi); } -auto matchPiTopLevel() { return matchFloatValueNear(Pi, false); } +auto matchPi() { return matchFloatValueNear(llvm::numbers::pi); } +auto matchPiTopLevel() { return matchFloatValueNear(llvm::numbers::pi, false); } -auto matchEgamma() { return matchFloatValueNear(Egamma, false); } +auto matchEgamma() { return matchFloatValueNear(llvm::numbers::egamma, false); } auto matchInvPi() { return expr( @@ -195,7 +190,7 @@ auto matchPhi() { hasOperatorName("+"), hasEitherOperand(matchValue(1)), hasEitherOperand(matchMathCall("sqrt", matchValue(5))))))), hasRHS(matchValue(2))); - return expr(anyOf(PhiFormula, matchFloatValueNear(Phi))); + return expr(anyOf(PhiFormula, matchFloatValueNear(llvm::numbers::phi))); } EditGenerator >From f879acd2a0d7108602e4c1a24ffeb94291490972 Mon Sep 17 00:00:00 2001 From: Julian Schmidt <44101708+5chmi...@users.noreply.github.com> Date: Sat, 7 Oct 2023 18:03:19 +0200 Subject: [PATCH 12/12] remove not needed argument for using a compile-time constant --- .../clang-tidy/modernize/UseStdNumbersCheck.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp index 799b5cc2aaa818e..9e8863c91d0ffe6 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp @@ -43,8 +43,8 @@ using llvm::StringRef; constexpr auto DiffThreshold = 0.001; -AST_MATCHER_P2(clang::FloatingLiteral, near, double, Value, double, Threshold) { - return std::abs(Node.getValue().convertToDouble() - Value) < Threshold; +AST_MATCHER_P(clang::FloatingLiteral, near, double, Value) { + return std::abs(Node.getValue().convertToDouble() - Value) < DiffThreshold; } // We don't want to match uses of macros, such as @@ -99,7 +99,7 @@ auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) { // Therefore, all top-level matcher set MatchDeclRefExprOrMacro to false auto matchFloatValueNear(const double Val, const bool MatchDeclRefExprOrMacro = true) { - const auto Float = floatLiteral(near(Val, DiffThreshold)); + const auto Float = floatLiteral(near(Val)); if (!MatchDeclRefExprOrMacro) { return expr(unless(isMacro()), ignoringImplicit(Float)); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits