forked from OSchip/llvm-project
83 lines
3.4 KiB
C++
83 lines
3.4 KiB
C++
//===--- UnusedReturnValueCheck.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 "UnusedReturnValueCheck.h"
|
|
#include "../utils/OptionsUtils.h"
|
|
#include "clang/AST/ASTContext.h"
|
|
#include "clang/ASTMatchers/ASTMatchFinder.h"
|
|
|
|
using namespace clang::ast_matchers;
|
|
using namespace clang::ast_matchers::internal;
|
|
|
|
namespace clang {
|
|
namespace tidy {
|
|
namespace bugprone {
|
|
|
|
UnusedReturnValueCheck::UnusedReturnValueCheck(llvm::StringRef Name,
|
|
ClangTidyContext *Context)
|
|
: ClangTidyCheck(Name, Context),
|
|
CheckedFunctions(Options.get("CheckedFunctions", "::std::async;"
|
|
"::std::launder;"
|
|
"::std::remove;"
|
|
"::std::remove_if;"
|
|
"::std::unique")) {}
|
|
|
|
void UnusedReturnValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
|
|
Options.store(Opts, "CheckedFunctions", CheckedFunctions);
|
|
}
|
|
|
|
void UnusedReturnValueCheck::registerMatchers(MatchFinder *Finder) {
|
|
auto FunVec = utils::options::parseStringList(CheckedFunctions);
|
|
auto MatchedCallExpr = expr(ignoringImplicit(ignoringParenImpCasts(
|
|
callExpr(
|
|
callee(functionDecl(
|
|
// Don't match void overloads of checked functions.
|
|
unless(returns(voidType())), hasAnyName(std::vector<StringRef>(
|
|
FunVec.begin(), FunVec.end())))))
|
|
.bind("match"))));
|
|
|
|
auto UnusedInCompoundStmt =
|
|
compoundStmt(forEach(MatchedCallExpr),
|
|
// The checker can't currently differentiate between the
|
|
// return statement and other statements inside GNU statement
|
|
// expressions, so disable the checker inside them to avoid
|
|
// false positives.
|
|
unless(hasParent(stmtExpr())));
|
|
auto UnusedInIfStmt =
|
|
ifStmt(eachOf(hasThen(MatchedCallExpr), hasElse(MatchedCallExpr)));
|
|
auto UnusedInWhileStmt = whileStmt(hasBody(MatchedCallExpr));
|
|
auto UnusedInDoStmt = doStmt(hasBody(MatchedCallExpr));
|
|
auto UnusedInForStmt =
|
|
forStmt(eachOf(hasLoopInit(MatchedCallExpr),
|
|
hasIncrement(MatchedCallExpr), hasBody(MatchedCallExpr)));
|
|
auto UnusedInRangeForStmt = cxxForRangeStmt(hasBody(MatchedCallExpr));
|
|
auto UnusedInCaseStmt = switchCase(forEach(MatchedCallExpr));
|
|
|
|
Finder->addMatcher(
|
|
stmt(anyOf(UnusedInCompoundStmt, UnusedInIfStmt, UnusedInWhileStmt,
|
|
UnusedInDoStmt, UnusedInForStmt, UnusedInRangeForStmt,
|
|
UnusedInCaseStmt)),
|
|
this);
|
|
}
|
|
|
|
void UnusedReturnValueCheck::check(const MatchFinder::MatchResult &Result) {
|
|
if (const auto *Matched = Result.Nodes.getNodeAs<CallExpr>("match")) {
|
|
diag(Matched->getLocStart(),
|
|
"the value returned by this function should be used")
|
|
<< Matched->getSourceRange();
|
|
diag(Matched->getLocStart(),
|
|
"cast the expression to void to silence this warning",
|
|
DiagnosticIDs::Note);
|
|
}
|
|
}
|
|
|
|
} // namespace bugprone
|
|
} // namespace tidy
|
|
} // namespace clang
|