Index: clang-tidy/cppcoreguidelines/AvoidGotoCheck.h =================================================================== --- /dev/null +++ clang-tidy/cppcoreguidelines/AvoidGotoCheck.h @@ -0,0 +1,36 @@ +//===--- AvoidGotoCheck.h - clang-tidy---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDGOTOCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDGOTOCHECK_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace cppcoreguidelines { + +/// The usage of `goto` has been discouraged for a long time and is diagnosed +/// with this check. +/// +/// For the user-facing documentation see: +/// 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) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace cppcoreguidelines +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_AVOIDGOTOCHECK_H Index: clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp =================================================================== --- /dev/null +++ clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp @@ -0,0 +1,34 @@ +//===--- AvoidGotoCheck.cpp - clang-tidy-----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "AvoidGotoCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace cppcoreguidelines { + +void AvoidGotoCheck::registerMatchers(MatchFinder *Finder) { + if (LangOpts.CPlusPlus) + Finder->addMatcher(gotoStmt().bind("goto"), this); +} + +void AvoidGotoCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Match = Result.Nodes.getNodeAs("goto"); + diag(Match->getLocation(), "goto is considered harmful; use high level " + "programming constructs instead") + << Match->getSourceRange(); +} + +} // namespace cppcoreguidelines +} // namespace tidy +} // namespace clang Index: clang-tidy/cppcoreguidelines/CMakeLists.txt =================================================================== --- clang-tidy/cppcoreguidelines/CMakeLists.txt +++ clang-tidy/cppcoreguidelines/CMakeLists.txt @@ -1,6 +1,7 @@ set(LLVM_LINK_COMPONENTS support) add_clang_library(clangTidyCppCoreGuidelinesModule + AvoidGotoCheck.cpp CppCoreGuidelinesTidyModule.cpp InterfacesGlobalInitCheck.cpp NoMallocCheck.cpp Index: clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp =================================================================== --- clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp +++ clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp @@ -11,6 +11,7 @@ #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" #include "../misc/UnconventionalAssignOperatorCheck.h" +#include "AvoidGotoCheck.h" #include "InterfacesGlobalInitCheck.h" #include "NoMallocCheck.h" #include "OwningMemoryCheck.h" @@ -35,6 +36,8 @@ class CppCoreGuidelinesModule : public ClangTidyModule { public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + CheckFactories.registerCheck( + "cppcoreguidelines-avoid-goto"); CheckFactories.registerCheck( "cppcoreguidelines-interfaces-global-init"); CheckFactories.registerCheck("cppcoreguidelines-no-malloc"); Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -57,6 +57,12 @@ Improvements to clang-tidy -------------------------- +- New `cppcoreguidelines-avoid-goto + `_ check + + The usage of ``goto`` has been discouraged for a long time and is diagnosed + with this check. + - ... Improvements to include-fixer Index: docs/clang-tidy/checks/cppcoreguidelines-avoid-goto.rst =================================================================== --- /dev/null +++ docs/clang-tidy/checks/cppcoreguidelines-avoid-goto.rst @@ -0,0 +1,11 @@ +.. title:: clang-tidy - cppcoreguidelines-avoid-goto + +cppcoreguidelines-avoid-goto +============================ + +The usage of ``goto`` has been discouraged for a long time and is diagnosed +with this check. + +This check implements `ES.76 `_ +from the CppCoreGuidelines. For more information on why to avoid programming +with ``goto`` you can read the famous paper `A Case against the GO TO Statement. `_. Index: docs/clang-tidy/checks/list.rst =================================================================== --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -52,6 +52,7 @@ cert-msc30-c (redirects to cert-msc50-cpp) cert-msc50-cpp cert-oop11-cpp (redirects to performance-move-constructor-init) + cppcoreguidelines-avoid-goto cppcoreguidelines-c-copy-assignment-signature (redirects to misc-unconventional-assign-operator) cppcoreguidelines-interfaces-global-init cppcoreguidelines-no-malloc Index: test/clang-tidy/cppcoreguidelines-avoid-goto.cpp =================================================================== --- /dev/null +++ test/clang-tidy/cppcoreguidelines-avoid-goto.cpp @@ -0,0 +1,7 @@ +// RUN: %check_clang_tidy %s cppcoreguidelines-avoid-goto %t + +int main() { +jump_to_me: + goto jump_to_me; + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: goto is considered harmful; use high level programming constructs instead +}