diff --git a/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp index 2f155820a83e5..a01b7f5a4ee6e 100644 --- a/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp @@ -19,6 +19,8 @@ namespace clang::tidy::bugprone { namespace { +static constexpr bool DefaultIgnoreMacros = false; + // Keep track of macro expansions that contain both __FILE__ and __LINE__. If // such a macro also uses __func__ or __FUNCTION__, we don't want to issue a // warning because __FILE__ and __LINE__ may be useful even if __func__ or @@ -56,6 +58,16 @@ class MacroExpansionsWithFileAndLine : public PPCallbacks { } // namespace +LambdaFunctionNameCheck::LambdaFunctionNameCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + IgnoreMacros( + Options.getLocalOrGlobal("IgnoreMacros", DefaultIgnoreMacros)) {} + +void LambdaFunctionNameCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IgnoreMacros", IgnoreMacros); +} + void LambdaFunctionNameCheck::registerMatchers(MatchFinder *Finder) { // Match on PredefinedExprs inside a lambda. Finder->addMatcher(predefinedExpr(hasAncestor(lambdaExpr())).bind("E"), @@ -76,6 +88,9 @@ void LambdaFunctionNameCheck::check(const MatchFinder::MatchResult &Result) { return; } if (E->getLocation().isMacroID()) { + if (IgnoreMacros) + return; + auto ER = Result.SourceManager->getImmediateExpansionRange(E->getLocation()); if (SuppressMacroExpansions.find(ER.getAsRange()) != @@ -84,6 +99,7 @@ void LambdaFunctionNameCheck::check(const MatchFinder::MatchResult &Result) { return; } } + diag(E->getLocation(), "inside a lambda, '%0' expands to the name of the function call " "operator; consider capturing the name of the enclosing function " diff --git a/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.h b/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.h index 03f1c4544aee1..dab64f74aa6ca 100644 --- a/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.h @@ -31,8 +31,9 @@ class LambdaFunctionNameCheck : public ClangTidyCheck { }; using SourceRangeSet = std::set; - LambdaFunctionNameCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} + LambdaFunctionNameCheck(StringRef Name, ClangTidyContext *Context); + + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; @@ -40,6 +41,7 @@ class LambdaFunctionNameCheck : public ClangTidyCheck { private: SourceRangeSet SuppressMacroExpansions; + bool IgnoreMacros; }; } // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index dffc838053f08..a80473f09464f 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -173,6 +173,10 @@ Changes in existing checks `, so that it does not warn on macros starting with underscore and lowercase letter. +- Improved :doc:`bugprone-lambda-function-name + ` check by adding option + `IgnoreMacros` to ignore warnings in macros. + - Improved :doc:`cppcoreguidelines-avoid-non-const-global-variables ` check to ignore ``static`` variables declared within the scope of diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/lambda-function-name.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/lambda-function-name.rst index 6f0ba836fdf5c..e9cbf2b46b2bc 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/lambda-function-name.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/lambda-function-name.rst @@ -25,3 +25,11 @@ Likely intended output:: Called from FancyFunction Now called from FancyFunction + +Options +------- + +.. option:: IgnoreMacros + + The value `true` specifies that attempting to get the name of a function from + within a macro should not be diagnosed. The default value is `false`. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/lambda-function-name.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/lambda-function-name.cpp index 145928b4e20d9..936ee87a856cd 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/lambda-function-name.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/lambda-function-name.cpp @@ -1,4 +1,6 @@ -// RUN: %check_clang_tidy %s bugprone-lambda-function-name %t +// RUN: %check_clang_tidy -check-suffixes=,NO-CONFIG %s bugprone-lambda-function-name %t +// RUN: %check_clang_tidy %s bugprone-lambda-function-name %t -- -config="{CheckOptions: [{key: bugprone-lambda-function-name.IgnoreMacros, value: true}]}" -- + void Foo(const char* a, const char* b, int c) {} @@ -12,11 +14,11 @@ void Positives() { [] { __FUNCTION__; }(); // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: inside a lambda, '__FUNCTION__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name] [] { FUNC_MACRO; }(); - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: inside a lambda, '__func__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name] + // CHECK-MESSAGES-NO-CONFIG: :[[@LINE-1]]:8: warning: inside a lambda, '__func__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name] [] { FUNCTION_MACRO; }(); - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: inside a lambda, '__FUNCTION__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name] + // CHECK-MESSAGES-NO-CONFIG: :[[@LINE-1]]:8: warning: inside a lambda, '__FUNCTION__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name] [] { EMBED_IN_ANOTHER_MACRO1; }(); - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: inside a lambda, '__func__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name] + // CHECK-MESSAGES-NO-CONFIG: :[[@LINE-1]]:8: warning: inside a lambda, '__func__' expands to the name of the function call operator; consider capturing the name of the enclosing function explicitly [bugprone-lambda-function-name] } #define FUNC_MACRO_WITH_FILE_AND_LINE Foo(__func__, __FILE__, __LINE__)