xref: /llvm-project/clang-tools-extra/clang-tidy/performance/NoexceptFunctionBaseCheck.cpp (revision 845618cf69e89313084a4e93f8ff31d8e6ea4499)
1 //===--- NoexceptFunctionCheck.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 "NoexceptFunctionBaseCheck.h"
10 #include "../utils/LexerUtils.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/AST/Decl.h"
13 #include "clang/ASTMatchers/ASTMatchFinder.h"
14 
15 using namespace clang::ast_matchers;
16 
17 namespace clang::tidy::performance {
18 
check(const MatchFinder::MatchResult & Result)19 void NoexceptFunctionBaseCheck::check(const MatchFinder::MatchResult &Result) {
20   const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>(BindFuncDeclName);
21   assert(FuncDecl);
22 
23   if (SpecAnalyzer.analyze(FuncDecl) !=
24       utils::ExceptionSpecAnalyzer::State::Throwing)
25     return;
26 
27   // Don't complain about nothrow(false), but complain on nothrow(expr)
28   // where expr evaluates to false.
29   const auto *ProtoType = FuncDecl->getType()->castAs<FunctionProtoType>();
30   const Expr *NoexceptExpr = ProtoType->getNoexceptExpr();
31   if (NoexceptExpr) {
32     NoexceptExpr = NoexceptExpr->IgnoreImplicit();
33     if (!isa<CXXBoolLiteralExpr>(NoexceptExpr))
34       reportNoexceptEvaluatedToFalse(FuncDecl, NoexceptExpr);
35     return;
36   }
37 
38   auto Diag = reportMissingNoexcept(FuncDecl);
39 
40   // Add FixIt hints.
41   const SourceManager &SM = *Result.SourceManager;
42 
43   const SourceLocation NoexceptLoc =
44       utils::lexer::getLocationForNoexceptSpecifier(FuncDecl, SM);
45   if (NoexceptLoc.isValid())
46     Diag << FixItHint::CreateInsertion(NoexceptLoc, " noexcept ");
47 }
48 
49 } // namespace clang::tidy::performance
50