clang-tools  14.0.0git
UnhandledExceptionAtNewCheck.cpp
Go to the documentation of this file.
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 
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 
13 using namespace clang::ast_matchers;
14 
15 namespace clang {
16 namespace tidy {
17 namespace bugprone {
18 
19 AST_MATCHER_P(CXXTryStmt, hasHandlerFor,
20  ast_matchers::internal::Matcher<QualType>, InnerMatcher) {
21  for (unsigned NH = Node.getNumHandlers(), I = 0; I < NH; ++I) {
22  const CXXCatchStmt *CatchS = Node.getHandler(I);
23  // Check for generic catch handler (match anything).
24  if (CatchS->getCaughtType().isNull())
25  return true;
26  ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder);
27  if (InnerMatcher.matches(CatchS->getCaughtType(), Finder, &Result)) {
28  *Builder = std::move(Result);
29  return true;
30  }
31  }
32  return false;
33 }
34 
35 AST_MATCHER(CXXNewExpr, mayThrow) {
36  FunctionDecl *OperatorNew = Node.getOperatorNew();
37  if (!OperatorNew)
38  return false;
39  return !OperatorNew->getType()->castAs<FunctionProtoType>()->isNothrow();
40 }
41 
42 UnhandledExceptionAtNewCheck::UnhandledExceptionAtNewCheck(
43  StringRef Name, ClangTidyContext *Context)
44  : ClangTidyCheck(Name, Context) {}
45 
47  auto BadAllocType =
48  recordType(hasDeclaration(cxxRecordDecl(hasName("::std::bad_alloc"))));
49  auto ExceptionType =
50  recordType(hasDeclaration(cxxRecordDecl(hasName("::std::exception"))));
51  auto BadAllocReferenceType = referenceType(pointee(BadAllocType));
52  auto ExceptionReferenceType = referenceType(pointee(ExceptionType));
53 
54  auto CatchBadAllocType =
55  qualType(hasCanonicalType(anyOf(BadAllocType, BadAllocReferenceType,
56  ExceptionType, ExceptionReferenceType)));
57  auto BadAllocCatchingTryBlock = cxxTryStmt(hasHandlerFor(CatchBadAllocType));
58 
59  auto FunctionMayNotThrow = functionDecl(isNoThrow());
60 
61  Finder->addMatcher(cxxNewExpr(mayThrow(),
62  unless(hasAncestor(BadAllocCatchingTryBlock)),
63  hasAncestor(FunctionMayNotThrow))
64  .bind("new-expr"),
65  this);
66 }
67 
69  const MatchFinder::MatchResult &Result) {
70  const auto *MatchedExpr = Result.Nodes.getNodeAs<CXXNewExpr>("new-expr");
71  if (MatchedExpr)
72  diag(MatchedExpr->getBeginLoc(),
73  "missing exception handler for allocation failure at 'new'");
74 }
75 
76 } // namespace bugprone
77 } // namespace tidy
78 } // namespace clang
clang::tidy::ClangTidyCheck
Base class for all clang-tidy checks.
Definition: ClangTidyCheck.h:54
UnhandledExceptionAtNewCheck.h
clang::ast_matchers
Definition: AbseilMatcher.h:14
Builder
CodeCompletionBuilder Builder
Definition: CodeCompletionStringsTests.cpp:36
clang::tidy::ClangTidyContext
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
Definition: ClangTidyDiagnosticConsumer.h:71
Name
static constexpr llvm::StringLiteral Name
Definition: UppercaseLiteralSuffixCheck.cpp:28
clang::tidy::bugprone::UnhandledExceptionAtNewCheck::check
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
Definition: UnhandledExceptionAtNewCheck.cpp:68
clang::tidy::ClangTidyCheck::diag
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
Definition: ClangTidyCheck.cpp:25
clang::ast_matchers::AST_MATCHER
AST_MATCHER(Expr, isMacroID)
Definition: PreferIsaOrDynCastInConditionalsCheck.cpp:19
clang::tidy::bugprone::AST_MATCHER_P
AST_MATCHER_P(CXXTryStmt, hasHandlerFor, ast_matchers::internal::Matcher< QualType >, InnerMatcher)
Definition: UnhandledExceptionAtNewCheck.cpp:19
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::tidy::bugprone::UnhandledExceptionAtNewCheck::registerMatchers
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
Definition: UnhandledExceptionAtNewCheck.cpp:46