11 #include "../utils/Matchers.h"
12 #include "../utils/OptionsUtils.h"
13 #include "clang/AST/ASTContext.h"
14 #include "clang/ASTMatchers/ASTMatchFinder.h"
19 using namespace clang::ast_matchers;
20 using namespace clang::ast_matchers::internal;
24 namespace cppcoreguidelines {
27 Matcher<FunctionDecl> hasAnyListedName(
const std::string &FunctionNames) {
28 const std::vector<std::string> NameList =
30 return hasAnyName(std::vector<StringRef>(NameList.begin(), NameList.end()));
35 Options.store(Opts,
"Allocations", AllocList);
36 Options.store(Opts,
"Reallocations", ReallocList);
37 Options.store(Opts,
"Deallocations", DeallocList);
40 void NoMallocCheck::registerMatchers(MatchFinder *
Finder) {
42 if (!getLangOpts().CPlusPlus)
46 Finder->addMatcher(callExpr(callee(functionDecl(hasAnyListedName(AllocList))))
52 callExpr(callee(functionDecl(hasAnyListedName(ReallocList))))
58 callExpr(callee(functionDecl(hasAnyListedName(DeallocList))))
63 void NoMallocCheck::check(
const MatchFinder::MatchResult &Result) {
64 const CallExpr *Call =
nullptr;
65 StringRef Recommendation;
67 if ((Call = Result.Nodes.getNodeAs<CallExpr>(
"allocation")))
68 Recommendation =
"consider a container or a smart pointer";
69 else if ((Call = Result.Nodes.getNodeAs<CallExpr>(
"realloc")))
70 Recommendation =
"consider std::vector or std::string";
71 else if ((Call = Result.Nodes.getNodeAs<CallExpr>(
"free")))
72 Recommendation =
"use RAII";
74 assert(Call &&
"Unhandled binding in the Matcher");
76 diag(Call->getLocStart(),
"do not manage memory manually; %0")
77 << Recommendation << SourceRange(Call->getLocStart(), Call->getLocEnd());
std::unique_ptr< ast_matchers::MatchFinder > Finder
std::vector< std::string > parseStringList(StringRef Option)
Parse a semicolon separated list of strings.
std::map< std::string, std::string > OptionMap