clang  13.0.0git
CalledOnceCheck.h
Go to the documentation of this file.
1 //===- CalledOnceCheck.h - Check 'called once' parameters -------*- C++ -*-===//
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 // This file defines a check for function-like parameters that should be
10 // called exactly one time.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_CALLEDONCECHECK_H
15 #define LLVM_CLANG_ANALYSIS_ANALYSES_CALLEDONCECHECK_H
16 
17 namespace clang {
18 
20 class BlockDecl;
21 class CFG;
22 class Decl;
23 class DeclContext;
24 class Expr;
25 class ParmVarDecl;
26 class Stmt;
27 
28 /// Classification of situations when parameter is not called on every path.
29 /// \enum IfThen -- then branch of the if statement has no call.
30 /// \enum IfElse -- else branch of the if statement has no call.
31 /// \enum Switch -- one of the switch cases doesn't have a call.
32 /// \enum SwitchSkipped -- there is no call if none of the cases appies.
33 /// \enum LoopEntered -- no call when the loop is entered.
34 /// \enum LoopSkipped -- no call when the loop is not entered.
35 /// \enum FallbackReason -- fallback case when we were not able to figure out
36 /// the reason.
37 enum class NeverCalledReason {
38  IfThen,
39  IfElse,
40  Switch,
46 };
47 
49 public:
50  CalledOnceCheckHandler() = default;
51  virtual ~CalledOnceCheckHandler() = default;
52 
53  /// Called when parameter is called twice.
54  /// \param Parameter -- parameter that should be called once.
55  /// \param Call -- call to report the warning.
56  /// \param PrevCall -- previous call.
57  /// \param IsCompletionHandler -- true, if parameter is a completion handler.
58  /// \param Poised -- true, if the second call is guaranteed to happen after
59  /// the first call.
60  virtual void handleDoubleCall(const ParmVarDecl *Parameter, const Expr *Call,
61  const Expr *PrevCall, bool IsCompletionHandler,
62  bool Poised) {}
63 
64  /// Called when parameter is not called at all.
65  /// \param Parameter -- parameter that should be called once.
66  /// \param IsCompletionHandler -- true, if parameter is a completion handler.
67  virtual void handleNeverCalled(const ParmVarDecl *Parameter,
68  bool IsCompletionHandler) {}
69 
70  /// Called when captured parameter is not called at all.
71  /// \param Parameter -- parameter that should be called once.
72  /// \param Where -- declaration that captures \p Parameter
73  /// \param IsCompletionHandler -- true, if parameter is a completion handler.
74  virtual void handleCapturedNeverCalled(const ParmVarDecl *Parameter,
75  const Decl *Where,
76  bool IsCompletionHandler) {}
77 
78  /// Called when parameter is not called on one of the paths.
79  /// Usually we try to find a statement that is the least common ancestor of
80  /// the path containing the call and not containing the call. This helps us
81  /// to pinpoint a bad path for the user.
82  /// \param Parameter -- parameter that should be called once.
83  /// \param Function -- function declaration where the problem occured.
84  /// \param Where -- the least common ancestor statement.
85  /// \param Reason -- a reason describing the path without a call.
86  /// \param IsCalledDirectly -- true, if parameter actually gets called on
87  /// the other path. It is opposed to be used in some other way (added to some
88  /// collection, passed as a parameter, etc.).
89  /// \param IsCompletionHandler -- true, if parameter is a completion handler.
90  virtual void handleNeverCalled(const ParmVarDecl *Parameter,
91  const Decl *Function, const Stmt *Where,
92  NeverCalledReason Reason,
93  bool IsCalledDirectly,
94  bool IsCompletionHandler) {}
95 
96  /// Called when the block is guaranteed to be called exactly once.
97  /// It means that we can be stricter with what we report on that block.
98  /// \param Block -- block declaration that is known to be called exactly once.
99  virtual void
101 
102  /// Called when the block has no guarantees about how many times it can get
103  /// called.
104  /// It means that we should be more lenient with reporting warnings in it.
105  /// \param Block -- block declaration in question.
106  virtual void handleBlockWithNoGuarantees(const BlockDecl *Block) {}
107 };
108 
109 /// Check given CFG for 'called once' parameter violations.
110 ///
111 /// It traverses the function and tracks how such parameters are used.
112 /// It detects two main violations:
113 /// * parameter is called twice
114 /// * parameter is not called
115 ///
116 /// \param AC -- context.
117 /// \param Handler -- a handler for found violations.
118 /// \param CheckConventionalParameters -- true, if we want to check parameters
119 /// not explicitly marked as 'called once', but having the same requirements
120 /// according to conventions.
121 void checkCalledOnceParameters(AnalysisDeclContext &AC,
122  CalledOnceCheckHandler &Handler,
123  bool CheckConventionalParameters);
124 
125 } // end namespace clang
126 
127 #endif /* LLVM_CLANG_ANALYSIS_ANALYSES_CALLEDONCECHECK_H */
clang::CalledOnceCheckHandler::CalledOnceCheckHandler
CalledOnceCheckHandler()=default
clang::CalledOnceCheckHandler::handleBlockThatIsGuaranteedToBeCalledOnce
virtual void handleBlockThatIsGuaranteedToBeCalledOnce(const BlockDecl *Block)
Called when the block is guaranteed to be called exactly once.
Definition: CalledOnceCheck.h:100
clang::CalledOnceCheckHandler
Definition: CalledOnceCheck.h:48
clang::DeclContext
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1347
clang::CalledOnceCheckHandler::handleDoubleCall
virtual void handleDoubleCall(const ParmVarDecl *Parameter, const Expr *Call, const Expr *PrevCall, bool IsCompletionHandler, bool Poised)
Called when parameter is called twice.
Definition: CalledOnceCheck.h:60
clang::checkCalledOnceParameters
void checkCalledOnceParameters(AnalysisDeclContext &AC, CalledOnceCheckHandler &Handler, bool CheckConventionalParameters)
Check given CFG for 'called once' parameter violations.
Definition: CalledOnceCheck.cpp:1700
clang::AnalysisDeclContext
AnalysisDeclContext contains the context data for the function, method or block under analysis.
Definition: AnalysisDeclContext.h:72
clang::ParmVarDecl
Represents a parameter to a function.
Definition: Decl.h:1634
clang::CalledOnceCheckHandler::handleCapturedNeverCalled
virtual void handleCapturedNeverCalled(const ParmVarDecl *Parameter, const Decl *Where, bool IsCompletionHandler)
Called when captured parameter is not called at all.
Definition: CalledOnceCheck.h:74
clang::NeverCalledReason::LoopSkipped
@ LoopSkipped
clang::CFG
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition: CFG.h:1225
clang::NeverCalledReason::LARGEST_VALUE
@ LARGEST_VALUE
clang::CalledOnceCheckHandler::handleBlockWithNoGuarantees
virtual void handleBlockWithNoGuarantees(const BlockDecl *Block)
Called when the block has no guarantees about how many times it can get called.
Definition: CalledOnceCheck.h:106
clang::BlockDecl
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4114
clang::NeverCalledReason::IfThen
@ IfThen
clang::CalledOnceCheckHandler::handleNeverCalled
virtual void handleNeverCalled(const ParmVarDecl *Parameter, const Decl *Function, const Stmt *Where, NeverCalledReason Reason, bool IsCalledDirectly, bool IsCompletionHandler)
Called when parameter is not called on one of the paths.
Definition: CalledOnceCheck.h:90
clang::NeverCalledReason::LoopEntered
@ LoopEntered
clang::NeverCalledReason::SwitchSkipped
@ SwitchSkipped
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
clang::NeverCalledReason
NeverCalledReason
Definition: CalledOnceCheck.h:37
clang::NeverCalledReason::FallbackReason
@ FallbackReason
clang::CalledOnceCheckHandler::handleNeverCalled
virtual void handleNeverCalled(const ParmVarDecl *Parameter, bool IsCompletionHandler)
Called when parameter is not called at all.
Definition: CalledOnceCheck.h:67
clang
Definition: CalledOnceCheck.h:17
clang::NeverCalledReason::Switch
@ Switch
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:68
clang::CalledOnceCheckHandler::~CalledOnceCheckHandler
virtual ~CalledOnceCheckHandler()=default
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::NeverCalledReason::IfElse
@ IfElse