1//===--- NoMallocCheck.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
9#include "NoMallocCheck.h"
10#include "../utils/OptionsUtils.h"
11#include "clang/ASTMatchers/ASTMatchFinder.h"
12
13using namespace clang::ast_matchers;
14using namespace clang::ast_matchers::internal;
15
16namespace clang::tidy::cppcoreguidelines {
17
18void NoMallocCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
19 Options.store(Options&: Opts, LocalName: "Allocations", Value: AllocList);
20 Options.store(Options&: Opts, LocalName: "Reallocations", Value: ReallocList);
21 Options.store(Options&: Opts, LocalName: "Deallocations", Value: DeallocList);
22}
23
24void NoMallocCheck::registerMatchers(MatchFinder *Finder) {
25 // Registering malloc, will suggest RAII.
26 Finder->addMatcher(NodeMatch: callExpr(callee(InnerMatcher: functionDecl(hasAnyName(
27 utils::options::parseStringList(Option: AllocList)))))
28 .bind(ID: "allocation"),
29 Action: this);
30
31 // Registering realloc calls, suggest std::vector or std::string.
32 Finder->addMatcher(
33 NodeMatch: callExpr(callee(InnerMatcher: functionDecl(
34 hasAnyName(utils::options::parseStringList(Option: (ReallocList))))))
35 .bind(ID: "realloc"),
36 Action: this);
37
38 // Registering free calls, will suggest RAII instead.
39 Finder->addMatcher(
40 NodeMatch: callExpr(callee(InnerMatcher: functionDecl(
41 hasAnyName(utils::options::parseStringList(Option: (DeallocList))))))
42 .bind(ID: "free"),
43 Action: this);
44}
45
46void NoMallocCheck::check(const MatchFinder::MatchResult &Result) {
47 const CallExpr *Call = nullptr;
48 StringRef Recommendation;
49
50 if ((Call = Result.Nodes.getNodeAs<CallExpr>(ID: "allocation")))
51 Recommendation = "consider a container or a smart pointer";
52 else if ((Call = Result.Nodes.getNodeAs<CallExpr>(ID: "realloc")))
53 Recommendation = "consider std::vector or std::string";
54 else if ((Call = Result.Nodes.getNodeAs<CallExpr>(ID: "free")))
55 Recommendation = "use RAII";
56
57 assert(Call && "Unhandled binding in the Matcher");
58
59 diag(Loc: Call->getBeginLoc(), Description: "do not manage memory manually; %0")
60 << Recommendation << SourceRange(Call->getBeginLoc(), Call->getEndLoc());
61}
62
63} // namespace clang::tidy::cppcoreguidelines
64

source code of clang-tools-extra/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp