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