clang-tools  14.0.0git
UnusedReturnValueCheck.cpp
Go to the documentation of this file.
1 //===--- UnusedReturnValueCheck.cpp - clang-tidy---------------------------===//
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 "../utils/OptionsUtils.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 
14 using namespace clang::ast_matchers;
15 using namespace clang::ast_matchers::internal;
16 
17 namespace clang {
18 namespace tidy {
19 namespace bugprone {
20 
21 namespace {
22 
23 // Matches functions that are instantiated from a class template member function
24 // matching InnerMatcher. Functions not instantiated from a class template
25 // member function are matched directly with InnerMatcher.
26 AST_MATCHER_P(FunctionDecl, isInstantiatedFrom, Matcher<FunctionDecl>,
27  InnerMatcher) {
28  FunctionDecl *InstantiatedFrom = Node.getInstantiatedFromMemberFunction();
29  return InnerMatcher.matches(InstantiatedFrom ? *InstantiatedFrom : Node,
30  Finder, Builder);
31 }
32 
33 } // namespace
34 
35 UnusedReturnValueCheck::UnusedReturnValueCheck(llvm::StringRef Name,
36  ClangTidyContext *Context)
37  : ClangTidyCheck(Name, Context),
38  CheckedFunctions(Options.get("CheckedFunctions",
39  "::std::async;"
40  "::std::launder;"
41  "::std::remove;"
42  "::std::remove_if;"
43  "::std::unique;"
44  "::std::unique_ptr::release;"
45  "::std::basic_string::empty;"
46  "::std::vector::empty;"
47  "::std::back_inserter;"
48  "::std::distance;"
49  "::std::find;"
50  "::std::find_if;"
51  "::std::inserter;"
52  "::std::lower_bound;"
53  "::std::make_pair;"
54  "::std::map::count;"
55  "::std::map::find;"
56  "::std::map::lower_bound;"
57  "::std::multimap::equal_range;"
58  "::std::multimap::upper_bound;"
59  "::std::set::count;"
60  "::std::set::find;"
61  "::std::setfill;"
62  "::std::setprecision;"
63  "::std::setw;"
64  "::std::upper_bound;"
65  "::std::vector::at;"
66  // C standard library
67  "::bsearch;"
68  "::ferror;"
69  "::feof;"
70  "::isalnum;"
71  "::isalpha;"
72  "::isblank;"
73  "::iscntrl;"
74  "::isdigit;"
75  "::isgraph;"
76  "::islower;"
77  "::isprint;"
78  "::ispunct;"
79  "::isspace;"
80  "::isupper;"
81  "::iswalnum;"
82  "::iswprint;"
83  "::iswspace;"
84  "::isxdigit;"
85  "::memchr;"
86  "::memcmp;"
87  "::strcmp;"
88  "::strcoll;"
89  "::strncmp;"
90  "::strpbrk;"
91  "::strrchr;"
92  "::strspn;"
93  "::strstr;"
94  "::wcscmp;"
95  // POSIX
96  "::access;"
97  "::bind;"
98  "::connect;"
99  "::difftime;"
100  "::dlsym;"
101  "::fnmatch;"
102  "::getaddrinfo;"
103  "::getopt;"
104  "::htonl;"
105  "::htons;"
106  "::iconv_open;"
107  "::inet_addr;"
108  "::isascii;"
109  "::isatty;"
110  "::mmap;"
111  "::newlocale;"
112  "::openat;"
113  "::pathconf;"
114  "::pthread_equal;"
115  "::pthread_getspecific;"
116  "::pthread_mutex_trylock;"
117  "::readdir;"
118  "::readlink;"
119  "::recvmsg;"
120  "::regexec;"
121  "::scandir;"
122  "::semget;"
123  "::setjmp;"
124  "::shm_open;"
125  "::shmget;"
126  "::sigismember;"
127  "::strcasecmp;"
128  "::strsignal;"
129  "::ttyname")) {}
130 
132  Options.store(Opts, "CheckedFunctions", CheckedFunctions);
133 }
134 
135 void UnusedReturnValueCheck::registerMatchers(MatchFinder *Finder) {
136  auto FunVec = utils::options::parseStringList(CheckedFunctions);
137  auto MatchedCallExpr = expr(ignoringImplicit(ignoringParenImpCasts(
138  callExpr(callee(functionDecl(
139  // Don't match void overloads of checked functions.
140  unless(returns(voidType())),
141  isInstantiatedFrom(hasAnyName(
142  std::vector<StringRef>(FunVec.begin(), FunVec.end()))))))
143  .bind("match"))));
144 
145  auto UnusedInCompoundStmt =
146  compoundStmt(forEach(MatchedCallExpr),
147  // The checker can't currently differentiate between the
148  // return statement and other statements inside GNU statement
149  // expressions, so disable the checker inside them to avoid
150  // false positives.
151  unless(hasParent(stmtExpr())));
152  auto UnusedInIfStmt =
153  ifStmt(eachOf(hasThen(MatchedCallExpr), hasElse(MatchedCallExpr)));
154  auto UnusedInWhileStmt = whileStmt(hasBody(MatchedCallExpr));
155  auto UnusedInDoStmt = doStmt(hasBody(MatchedCallExpr));
156  auto UnusedInForStmt =
157  forStmt(eachOf(hasLoopInit(MatchedCallExpr),
158  hasIncrement(MatchedCallExpr), hasBody(MatchedCallExpr)));
159  auto UnusedInRangeForStmt = cxxForRangeStmt(hasBody(MatchedCallExpr));
160  auto UnusedInCaseStmt = switchCase(forEach(MatchedCallExpr));
161 
162  Finder->addMatcher(
163  stmt(anyOf(UnusedInCompoundStmt, UnusedInIfStmt, UnusedInWhileStmt,
164  UnusedInDoStmt, UnusedInForStmt, UnusedInRangeForStmt,
165  UnusedInCaseStmt)),
166  this);
167 }
168 
169 void UnusedReturnValueCheck::check(const MatchFinder::MatchResult &Result) {
170  if (const auto *Matched = Result.Nodes.getNodeAs<CallExpr>("match")) {
171  diag(Matched->getBeginLoc(),
172  "the value returned by this function should be used")
173  << Matched->getSourceRange();
174  diag(Matched->getBeginLoc(),
175  "cast the expression to void to silence this warning",
176  DiagnosticIDs::Note);
177  }
178 }
179 
180 } // namespace bugprone
181 } // namespace tidy
182 } // namespace clang
clang::tidy::ClangTidyOptions::OptionMap
llvm::StringMap< ClangTidyValue > OptionMap
Definition: ClangTidyOptions.h:115
clang::tidy::ClangTidyCheck
Base class for all clang-tidy checks.
Definition: ClangTidyCheck.h:54
clang::ast_matchers
Definition: AbseilMatcher.h:14
clang::tidy::utils::options::parseStringList
std::vector< std::string > parseStringList(StringRef Option)
Parse a semicolon separated list of strings.
Definition: OptionsUtils.cpp:18
clang::tidy::bugprone::UnusedReturnValueCheck::storeOptions
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Should store all options supported by this check with their current values or default values for opti...
Definition: UnusedReturnValueCheck.cpp:131
clang::tidy::ClangTidyCheck::Options
OptionsView Options
Definition: ClangTidyCheck.h:416
Builder
CodeCompletionBuilder Builder
Definition: CodeCompletionStringsTests.cpp:36
clang::tidy::ClangTidyContext
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
Definition: ClangTidyDiagnosticConsumer.h:71
Name
static constexpr llvm::StringLiteral Name
Definition: UppercaseLiteralSuffixCheck.cpp:28
clang::tidy::ClangTidyCheck::diag
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
Definition: ClangTidyCheck.cpp:25
UnusedReturnValueCheck.h
clang::tidy::bugprone::UnusedReturnValueCheck::check
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
Definition: UnusedReturnValueCheck.cpp:169
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::tidy::ClangTidyCheck::OptionsView::store
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, StringRef Value) const
Stores an option with the check-local name LocalName with string value Value to Options.
Definition: ClangTidyCheck.cpp:120
clang::tidy::bugprone::UnusedReturnValueCheck::registerMatchers
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
Definition: UnusedReturnValueCheck.cpp:135
clang::tidy::bugprone::AST_MATCHER_P
AST_MATCHER_P(FunctionDecl, parameterCountGE, unsigned, N)
Matches functions that have at least the specified amount of parameters.
Definition: EasilySwappableParametersCheck.cpp:1877