NoEscapeCheck.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. //===--- NoEscapeCheck.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. #include "NoEscapeCheck.h"
  9. #include "clang/AST/ASTContext.h"
  10. #include "clang/ASTMatchers/ASTMatchFinder.h"
  11. using namespace clang::ast_matchers;
  12. namespace clang::tidy::bugprone {
  13. void NoEscapeCheck::registerMatchers(MatchFinder *Finder) {
  14. Finder->addMatcher(callExpr(callee(functionDecl(hasName("::dispatch_async"))),
  15. argumentCountIs(2),
  16. hasArgument(1, blockExpr().bind("arg-block"))),
  17. this);
  18. Finder->addMatcher(callExpr(callee(functionDecl(hasName("::dispatch_after"))),
  19. argumentCountIs(3),
  20. hasArgument(2, blockExpr().bind("arg-block"))),
  21. this);
  22. }
  23. void NoEscapeCheck::check(const MatchFinder::MatchResult &Result) {
  24. const auto *MatchedEscapingBlock =
  25. Result.Nodes.getNodeAs<BlockExpr>("arg-block");
  26. const BlockDecl *EscapingBlockDecl = MatchedEscapingBlock->getBlockDecl();
  27. for (const BlockDecl::Capture &CapturedVar : EscapingBlockDecl->captures()) {
  28. const VarDecl *Var = CapturedVar.getVariable();
  29. if (Var && Var->hasAttr<NoEscapeAttr>()) {
  30. // FIXME: Add a method to get the location of the use of a CapturedVar so
  31. // that we can diagnose the use of the pointer instead of the block.
  32. diag(MatchedEscapingBlock->getBeginLoc(),
  33. "pointer %0 with attribute 'noescape' is captured by an "
  34. "asynchronously-executed block")
  35. << Var;
  36. diag(Var->getBeginLoc(), "the 'noescape' attribute is declared here.",
  37. DiagnosticIDs::Note);
  38. }
  39. }
  40. }
  41. } // namespace clang::tidy::bugprone