10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
19 void NoEscapeCheck::registerMatchers(MatchFinder *Finder) {
20 Finder->addMatcher(callExpr(callee(functionDecl(hasName(
"::dispatch_async"))),
22 hasArgument(1, blockExpr().bind(
"arg-block"))),
24 Finder->addMatcher(callExpr(callee(functionDecl(hasName(
"::dispatch_after"))),
26 hasArgument(2, blockExpr().bind(
"arg-block"))),
30 void NoEscapeCheck::check(
const MatchFinder::MatchResult &Result) {
31 const auto *MatchedEscapingBlock =
32 Result.Nodes.getNodeAs<BlockExpr>(
"arg-block");
33 const BlockDecl *EscapingBlockDecl = MatchedEscapingBlock->getBlockDecl();
34 for (
const BlockDecl::Capture &CapturedVar : EscapingBlockDecl->captures()) {
35 const VarDecl *Var = CapturedVar.getVariable();
36 if (Var && Var->hasAttr<NoEscapeAttr>()) {
39 diag(MatchedEscapingBlock->getBeginLoc(),
40 "pointer %0 with attribute 'noescape' is captured by an "
41 "asynchronously-executed block")
43 diag(Var->getBeginLoc(),
"the 'noescape' attribute is declared here.",