11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 #include "clang/Lex/Lexer.h"
15 using namespace clang::ast_matchers;
21 void CloexecCreatCheck::registerMatchers(MatchFinder *
Finder) {
22 auto CharPointerType = hasType(pointerType(pointee(isAnyCharacter())));
23 auto MODETType = hasType(namedDecl(hasName(
"mode_t")));
26 callExpr(callee(functionDecl(isExternC(), returns(isInteger()),
28 hasParameter(0, CharPointerType),
29 hasParameter(1, MODETType))
35 void CloexecCreatCheck::check(
const MatchFinder::MatchResult &Result) {
36 const auto *MatchedCall = Result.Nodes.getNodeAs<CallExpr>(
"creatFn");
37 const SourceManager &
SM = *Result.SourceManager;
39 const std::string &ReplacementText =
41 Lexer::getSourceText(CharSourceRange::getTokenRange(
42 MatchedCall->getArg(0)->getSourceRange()),
43 SM, Result.Context->getLangOpts()) +
44 ", O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, " +
45 Lexer::getSourceText(CharSourceRange::getTokenRange(
46 MatchedCall->getArg(1)->getSourceRange()),
47 SM, Result.Context->getLangOpts()) +
51 diag(MatchedCall->getLocStart(),
52 "prefer open() to creat() because open() allows O_CLOEXEC")
53 << FixItHint::CreateReplacement(MatchedCall->getSourceRange(),
std::unique_ptr< ast_matchers::MatchFinder > Finder