llvm-project

Форк
0
/
UnhandledExceptionAtNewCheck.cpp 
74 строки · 2.8 Кб
1
//===--- UnhandledExceptionAtNewCheck.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 "UnhandledExceptionAtNewCheck.h"
10
#include "clang/AST/ASTContext.h"
11
#include "clang/ASTMatchers/ASTMatchFinder.h"
12

13
using namespace clang::ast_matchers;
14

15
namespace clang::tidy::bugprone {
16

17
AST_MATCHER_P(CXXTryStmt, hasHandlerFor,
18
              ast_matchers::internal::Matcher<QualType>, InnerMatcher) {
19
  for (unsigned NH = Node.getNumHandlers(), I = 0; I < NH; ++I) {
20
    const CXXCatchStmt *CatchS = Node.getHandler(I);
21
    // Check for generic catch handler (match anything).
22
    if (CatchS->getCaughtType().isNull())
23
      return true;
24
    ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder);
25
    if (InnerMatcher.matches(CatchS->getCaughtType(), Finder, &Result)) {
26
      *Builder = std::move(Result);
27
      return true;
28
    }
29
  }
30
  return false;
31
}
32

33
AST_MATCHER(CXXNewExpr, mayThrow) {
34
  FunctionDecl *OperatorNew = Node.getOperatorNew();
35
  if (!OperatorNew)
36
    return false;
37
  return !OperatorNew->getType()->castAs<FunctionProtoType>()->isNothrow();
38
}
39

40
UnhandledExceptionAtNewCheck::UnhandledExceptionAtNewCheck(
41
    StringRef Name, ClangTidyContext *Context)
42
    : ClangTidyCheck(Name, Context) {}
43

44
void UnhandledExceptionAtNewCheck::registerMatchers(MatchFinder *Finder) {
45
  auto BadAllocType =
46
      recordType(hasDeclaration(cxxRecordDecl(hasName("::std::bad_alloc"))));
47
  auto ExceptionType =
48
      recordType(hasDeclaration(cxxRecordDecl(hasName("::std::exception"))));
49
  auto BadAllocReferenceType = referenceType(pointee(BadAllocType));
50
  auto ExceptionReferenceType = referenceType(pointee(ExceptionType));
51

52
  auto CatchBadAllocType =
53
      qualType(hasCanonicalType(anyOf(BadAllocType, BadAllocReferenceType,
54
                                      ExceptionType, ExceptionReferenceType)));
55
  auto BadAllocCatchingTryBlock = cxxTryStmt(hasHandlerFor(CatchBadAllocType));
56

57
  auto FunctionMayNotThrow = functionDecl(isNoThrow());
58

59
  Finder->addMatcher(cxxNewExpr(mayThrow(),
60
                                unless(hasAncestor(BadAllocCatchingTryBlock)),
61
                                hasAncestor(FunctionMayNotThrow))
62
                         .bind("new-expr"),
63
                     this);
64
}
65

66
void UnhandledExceptionAtNewCheck::check(
67
    const MatchFinder::MatchResult &Result) {
68
  const auto *MatchedExpr = Result.Nodes.getNodeAs<CXXNewExpr>("new-expr");
69
  if (MatchedExpr)
70
    diag(MatchedExpr->getBeginLoc(),
71
         "missing exception handler for allocation failure at 'new'");
72
}
73

74
} // namespace clang::tidy::bugprone
75

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.