diff options
author | Daniel Jasper <djasper@google.com> | 2015-01-14 19:37:54 +0000 |
---|---|---|
committer | Daniel Jasper <djasper@google.com> | 2015-01-14 19:37:54 +0000 |
commit | 3b6018b9f694546a9244a5ecca06be4c56b4410b (patch) | |
tree | 77b68faf02e71b506176e4e2549661d57258b639 | |
parent | fd41e2f946ec70e7ef2bd702ac8a56de97957e7b (diff) | |
download | bcm5719-llvm-3b6018b9f694546a9244a5ecca06be4c56b4410b.tar.gz bcm5719-llvm-3b6018b9f694546a9244a5ecca06be4c56b4410b.zip |
clang-tidy: Add initial check for "Don't use else after return".
As per the LLVM coding standards:
http://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return
Initial version, probably still quite a bit to do until this is really
useful.
Review: http://reviews.llvm.org/D6927
llvm-svn: 226025
5 files changed, 108 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index cf1248c196a..5d8031c3bf3 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS support) add_clang_library(clangTidyReadabilityModule BracesAroundStatementsCheck.cpp + ElseAfterReturnCheck.cpp FunctionSize.cpp NamespaceCommentCheck.cpp ReadabilityTidyModule.cpp diff --git a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp new file mode 100644 index 00000000000..9dd0c13f623 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp @@ -0,0 +1,46 @@ +//===--- ElseAfterReturnCheck.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 "ElseAfterReturnCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { + +void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) { + // FIXME: Support continue, break and throw. + Finder->addMatcher( + ifStmt( + hasThen(stmt(anyOf(returnStmt(), compoundStmt(has(returnStmt()))))), + hasElse(stmt().bind("else"))).bind("if"), + this); +} + +static FixItHint removeToken(SourceLocation Loc) { + return FixItHint::CreateRemoval(CharSourceRange::getTokenRange(Loc, Loc)); +} + +void ElseAfterReturnCheck::check(const MatchFinder::MatchResult &Result) { + const auto *If = Result.Nodes.getNodeAs<IfStmt>("if"); + SourceLocation ElseLoc = If->getElseLoc(); + DiagnosticBuilder Diag = diag(ElseLoc, "don't use else after return"); + Diag << removeToken(ElseLoc); + + // FIXME: Removing the braces isn't always safe. Do a more careful analysis. + // FIXME: Change clang-format to correctly un-indent the code. + if (const auto *CS = Result.Nodes.getNodeAs<CompoundStmt>("else")) + Diag << removeToken(CS->getLBracLoc()) << removeToken(CS->getRBracLoc()); +} + +} // namespace tidy +} // namespace clang + diff --git a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.h b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.h new file mode 100644 index 00000000000..2d2b4fb42a2 --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.h @@ -0,0 +1,30 @@ +//===--- ElseAfterReturnCheck.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_READABILITY_ELSE_AFTER_RETURN_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_ELSE_AFTER_RETURN_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { + +class ElseAfterReturnCheck : public ClangTidyCheck { +public: + ElseAfterReturnCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_ELSE_AFTER_RETURN_H + diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp index 9e7187573c9..71bac790a58 100644 --- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp @@ -11,6 +11,7 @@ #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" #include "BracesAroundStatementsCheck.h" +#include "ElseAfterReturnCheck.h" #include "FunctionSize.h" #include "RedundantSmartptrGet.h" @@ -23,6 +24,8 @@ public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck<BracesAroundStatementsCheck>( "readability-braces-around-statements"); + CheckFactories.registerCheck<ElseAfterReturnCheck>( + "readability-else-after-return"); CheckFactories.registerCheck<FunctionSizeCheck>( "readability-function-size"); CheckFactories.registerCheck<RedundantSmartptrGet>( diff --git a/clang-tools-extra/test/clang-tidy/readability-else-after-return.cpp b/clang-tools-extra/test/clang-tidy/readability-else-after-return.cpp new file mode 100644 index 00000000000..c94e71ba118 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/readability-else-after-return.cpp @@ -0,0 +1,28 @@ +// RUN: $(dirname %s)/check_clang_tidy.sh %s readability-else-after-return %t +// REQUIRES: shell + +void f(int a) { + if (a > 0) + return; + else // comment +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: don't use else after return +// CHECK-FIXES: {{^}} // comment + return; + + if (a > 0) { + return; + } else { // comment +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: don't use else after return +// CHECK-FIXES: } // comment + return; + } + + if (a > 0) { + f(0); + if (a > 10) + return; + } else { + return; + } +} + |