clang-tools 22.0.0git
RedundantControlFlowCheck.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "clang/ASTMatchers/ASTMatchFinder.h"
11#include "clang/ASTMatchers/ASTMatchersMacros.h"
12#include "clang/Lex/Lexer.h"
13
14using namespace clang::ast_matchers;
15
17
18namespace {
19
20AST_MATCHER_P(CompoundStmt, hasFinalStmt, StatementMatcher, InnerMatcher) {
21 return !Node.body_empty() &&
22 InnerMatcher.matches(*Node.body_back(), Finder, Builder);
23}
24
25} // namespace
26
27static constexpr StringRef RedundantReturnDiag =
28 "redundant return statement at the end "
29 "of a function with a void return type";
30static constexpr StringRef RedundantContinueDiag =
31 "redundant continue statement at the "
32 "end of loop statement";
33
35 Finder->addMatcher(
36 functionDecl(returns(voidType()),
37 hasBody(compoundStmt(hasFinalStmt(
38 returnStmt(unless(has(expr()))).bind("stmt"))))),
39 this);
40 Finder->addMatcher(mapAnyOf(forStmt, cxxForRangeStmt, whileStmt, doStmt)
41 .with(hasBody(compoundStmt(
42 hasFinalStmt(continueStmt().bind("stmt"))))),
43 this);
44}
45
46void RedundantControlFlowCheck::check(const MatchFinder::MatchResult &Result) {
47 const auto &RedundantStmt = *Result.Nodes.getNodeAs<Stmt>("stmt");
48 const SourceRange StmtRange = RedundantStmt.getSourceRange();
49
50 if (StmtRange.getBegin().isMacroID())
51 return;
52
53 const auto RemovedRange = CharSourceRange::getCharRange(
54 StmtRange.getBegin(),
55 Lexer::findLocationAfterToken(StmtRange.getEnd(), tok::semi,
56 *Result.SourceManager, getLangOpts(),
57 /*SkipTrailingWhitespaceAndNewLine=*/true));
58
59 diag(StmtRange.getBegin(), isa<ReturnStmt>(RedundantStmt)
62 << FixItHint::CreateRemoval(RemovedRange);
63}
64
65} // namespace clang::tidy::readability
void registerMatchers(ast_matchers::MatchFinder *Finder) override
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
AST_MATCHER_P(Stmt, isStatementIdenticalToBoundNode, std::string, ID)
static constexpr StringRef RedundantReturnDiag
static constexpr StringRef RedundantContinueDiag