https://github.com/vbvictor updated https://github.com/llvm/llvm-project/pull/143554
>From 5c975c6b59c02b0464a9bfc1b424b89b4d7dd662 Mon Sep 17 00:00:00 2001 From: Victor Baranov <bar.victor.2...@gmail.com> Date: Tue, 10 Jun 2025 18:27:12 +0300 Subject: [PATCH 1/3] [clang-tidy] add 'IgnoreMarcos' option to 'avoid-goto' check --- .../cppcoreguidelines/AvoidGotoCheck.cpp | 17 ++++++- .../cppcoreguidelines/AvoidGotoCheck.h | 7 ++- .../checks/cppcoreguidelines/avoid-goto.rst | 9 ++++ .../checkers/cppcoreguidelines/avoid-goto.cpp | 50 ++++++++++++++++--- 4 files changed, 72 insertions(+), 11 deletions(-) diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp index 8ffa44d41fa98..00864b1d69618 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp @@ -17,8 +17,20 @@ namespace { AST_MATCHER(GotoStmt, isForwardJumping) { return Node.getBeginLoc() < Node.getLabel()->getBeginLoc(); } + +AST_MATCHER(GotoStmt, isInMacro) { + return Node.getBeginLoc().isMacroID() && Node.getEndLoc().isMacroID(); +} } // namespace +AvoidGotoCheck::AvoidGotoCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + IgnoreMacros(Options.get("IgnoreMacros", true)) {} + +void AvoidGotoCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IgnoreMacros", IgnoreMacros); +} + void AvoidGotoCheck::registerMatchers(MatchFinder *Finder) { // TODO: This check does not recognize `IndirectGotoStmt` which is a // GNU extension. These must be matched separately and an AST matcher @@ -29,7 +41,10 @@ void AvoidGotoCheck::registerMatchers(MatchFinder *Finder) { auto Loop = mapAnyOf(forStmt, cxxForRangeStmt, whileStmt, doStmt); auto NestedLoop = Loop.with(hasAncestor(Loop)); - Finder->addMatcher(gotoStmt(anyOf(unless(hasAncestor(NestedLoop)), + const ast_matchers::internal::Matcher<GotoStmt> Anything = anything(); + + Finder->addMatcher(gotoStmt(IgnoreMacros ? unless(isInMacro()) : Anything, + anyOf(unless(hasAncestor(NestedLoop)), unless(isForwardJumping()))) .bind("goto"), this); diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h index 883ba78855e7c..8eae409462c91 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h @@ -20,13 +20,16 @@ namespace clang::tidy::cppcoreguidelines { /// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/avoid-goto.html class AvoidGotoCheck : public ClangTidyCheck { public: - AvoidGotoCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} + AvoidGotoCheck(StringRef Name, ClangTidyContext *Context); bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { return LangOpts.CPlusPlus; } + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + +private: + const bool IgnoreMacros; }; } // namespace clang::tidy::cppcoreguidelines diff --git a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-goto.rst b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-goto.rst index 71b579a4ae99e..823b3c376e6d0 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-goto.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-goto.rst @@ -50,3 +50,12 @@ Modern C++ needs ``goto`` only to jump out of nested loops. some_operation(); All other uses of ``goto`` are diagnosed in `C++`. + + +Options +------- + +.. option:: IgnoreMacros + + If set to `true`, the check will not warn if both label and ``goto`` + statement are placed inside a macro. Default is `true`. diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-goto.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-goto.cpp index ee236bc44695a..9a95b21cf3411 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-goto.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-goto.cpp @@ -1,12 +1,13 @@ // RUN: %check_clang_tidy %s cppcoreguidelines-avoid-goto %t +// RUN: %check_clang_tidy -check-suffix=,MACRO %s cppcoreguidelines-avoid-goto %t -- -config="{CheckOptions: { cppcoreguidelines-avoid-goto.IgnoreMacros: false }}" void noop() {} int main() { noop(); goto jump_to_me; - // CHECK-NOTES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control - // CHECK-NOTES: [[@LINE+3]]:1: note: label defined here + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES: [[@LINE+3]]:1: note: label defined here noop(); jump_to_me:; @@ -14,14 +15,14 @@ jump_to_me:; jump_backwards:; noop(); goto jump_backwards; - // CHECK-NOTES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control - // CHECK-NOTES: [[@LINE-4]]:1: note: label defined here + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES: [[@LINE-4]]:1: note: label defined here goto jump_in_line; ; jump_in_line:; - // CHECK-NOTES: [[@LINE-3]]:3: warning: avoid using 'goto' for flow control - // CHECK-NOTES: [[@LINE-2]]:1: note: label defined here + // CHECK-MESSAGES: [[@LINE-3]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES: [[@LINE-2]]:1: note: label defined here // Test the GNU extension https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html some_label:; @@ -132,8 +133,41 @@ void jump_out_backwards() { for (int j = 0; j < 10; ++j) { if (i * j > 80) goto before_the_loop; - // CHECK-NOTES: [[@LINE-1]]:9: warning: avoid using 'goto' for flow control - // CHECK-NOTES: [[@LINE-8]]:1: note: label defined here + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES: [[@LINE-8]]:1: note: label defined here } } } + +#define macro_goto_code \ + noop(); \ + goto jump_to_me; \ + noop(); \ +jump_to_me:; \ + +#define macro_goto_label jump_to_me:; +#define macro_goto_jump goto jump_to_me; + +void inside_macro_all() { + macro_goto_code + // CHECK-MESSAGES-MACRO: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES-MACRO: [[@LINE-2]]:3: note: label defined here +} + +void inside_macro_label() { + noop(); + goto jump_to_me; + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES: [[@LINE+2]]:3: note: label defined here + noop(); + macro_goto_label +} + +void inside_macro_goto() { + noop(); + macro_goto_jump + // CHECK-MESSAGES-MACRO: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES-MACRO: [[@LINE+2]]:3: note: label defined here + noop(); + jump_to_me:; +} >From a45d15f7a2ddfda45d6de6ab45c7ff6de05ec51d Mon Sep 17 00:00:00 2001 From: Victor Baranov <bar.victor.2...@gmail.com> Date: Tue, 10 Jun 2025 18:29:27 +0300 Subject: [PATCH 2/3] add release notes --- clang-tools-extra/docs/ReleaseNotes.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 19ccd1790e757..13219309276b9 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -191,11 +191,19 @@ Changes in existing checks <clang-tidy/checks/concurrency/mt-unsafe>` check by fixing a false positive where ``strerror`` was flagged as MT-unsafe. +- Improved :doc:`cppcoreguidelines-avoid-goto + <clang-tidy/checks/cppcoreguidelines/avoid-goto>` check by adding the option + `IgnoreMacros` to ignore ``goto`` labels defined in macros. + - Improved :doc:`google-readability-namespace-comments <clang-tidy/checks/google/readability-namespace-comments>` check by adding the option `AllowOmittingNamespaceComments` to accept if a namespace comment is omitted entirely. +- Improved :doc:`hicpp-avoid-goto + <clang-tidy/checks/hicpp/avoid-goto>` check by adding the option + `IgnoreMacros` to ignore ``goto`` labels defined in macros. + - Improved :doc:`llvm-namespace-comment <clang-tidy/checks/llvm/namespace-comment>` check by adding the option `AllowOmittingNamespaceComments` to accept if a namespace comment is omitted >From 2ae8a9a26f1eb731057bb668e1db050ac27e5053 Mon Sep 17 00:00:00 2001 From: Victor Baranov <bar.victor.2...@gmail.com> Date: Sun, 15 Jun 2025 22:39:45 +0300 Subject: [PATCH 3/3] Changed default value to 'false' and corrected docs --- .../cppcoreguidelines/AvoidGotoCheck.cpp | 2 +- .../checks/cppcoreguidelines/avoid-goto.rst | 4 ++-- .../checkers/cppcoreguidelines/avoid-goto.cpp | 24 +++++++++++++------ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp index 00864b1d69618..b14587ad7db83 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp @@ -25,7 +25,7 @@ AST_MATCHER(GotoStmt, isInMacro) { AvoidGotoCheck::AvoidGotoCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), - IgnoreMacros(Options.get("IgnoreMacros", true)) {} + IgnoreMacros(Options.get("IgnoreMacros", false)) {} void AvoidGotoCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "IgnoreMacros", IgnoreMacros); diff --git a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-goto.rst b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-goto.rst index 823b3c376e6d0..143b8c86cf334 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-goto.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/avoid-goto.rst @@ -57,5 +57,5 @@ Options .. option:: IgnoreMacros - If set to `true`, the check will not warn if both label and ``goto`` - statement are placed inside a macro. Default is `true`. + If set to `true`, the check will not warn if ``goto`` statement is placed + inside a macro. Default is `false`. diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-goto.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-goto.cpp index 9a95b21cf3411..d1c59e77f5972 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-goto.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/avoid-goto.cpp @@ -1,5 +1,5 @@ // RUN: %check_clang_tidy %s cppcoreguidelines-avoid-goto %t -// RUN: %check_clang_tidy -check-suffix=,MACRO %s cppcoreguidelines-avoid-goto %t -- -config="{CheckOptions: { cppcoreguidelines-avoid-goto.IgnoreMacros: false }}" +// RUN: %check_clang_tidy -check-suffix=MACRO %s cppcoreguidelines-avoid-goto %t -- -config="{CheckOptions: { cppcoreguidelines-avoid-goto.IgnoreMacros: true }}" void noop() {} @@ -7,7 +7,9 @@ int main() { noop(); goto jump_to_me; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control - // CHECK-MESSAGES: [[@LINE+3]]:1: note: label defined here + // CHECK-MESSAGES: [[@LINE+5]]:1: note: label defined here + // CHECK-MESSAGES-MACRO: [[@LINE-3]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES-MACRO: [[@LINE+3]]:1: note: label defined here noop(); jump_to_me:; @@ -17,12 +19,16 @@ jump_backwards:; goto jump_backwards; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control // CHECK-MESSAGES: [[@LINE-4]]:1: note: label defined here + // CHECK-MESSAGES-MACRO: [[@LINE-3]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES-MACRO: [[@LINE-6]]:1: note: label defined here goto jump_in_line; ; jump_in_line:; // CHECK-MESSAGES: [[@LINE-3]]:3: warning: avoid using 'goto' for flow control // CHECK-MESSAGES: [[@LINE-2]]:1: note: label defined here + // CHECK-MESSAGES-MACRO: [[@LINE-5]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES-MACRO: [[@LINE-4]]:1: note: label defined here // Test the GNU extension https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html some_label:; @@ -135,6 +141,8 @@ void jump_out_backwards() { goto before_the_loop; // CHECK-MESSAGES: [[@LINE-1]]:9: warning: avoid using 'goto' for flow control // CHECK-MESSAGES: [[@LINE-8]]:1: note: label defined here + // CHECK-MESSAGES-MACRO: [[@LINE-3]]:9: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES-MACRO: [[@LINE-10]]:1: note: label defined here } } } @@ -150,15 +158,17 @@ jump_to_me:; \ void inside_macro_all() { macro_goto_code - // CHECK-MESSAGES-MACRO: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control - // CHECK-MESSAGES-MACRO: [[@LINE-2]]:3: note: label defined here + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES: [[@LINE-2]]:3: note: label defined here } void inside_macro_label() { noop(); goto jump_to_me; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control - // CHECK-MESSAGES: [[@LINE+2]]:3: note: label defined here + // CHECK-MESSAGES: [[@LINE+4]]:3: note: label defined here + // CHECK-MESSAGES-MACRO: [[@LINE-3]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES-MACRO: [[@LINE+2]]:3: note: label defined here noop(); macro_goto_label } @@ -166,8 +176,8 @@ void inside_macro_label() { void inside_macro_goto() { noop(); macro_goto_jump - // CHECK-MESSAGES-MACRO: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control - // CHECK-MESSAGES-MACRO: [[@LINE+2]]:3: note: label defined here + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control + // CHECK-MESSAGES: [[@LINE+2]]:3: note: label defined here noop(); jump_to_me:; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits