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
17namespace clang {
18
19class AnalysisDeclContext;
20class BlockDecl;
21class CFG;
22class Decl;
23class Expr;
24class ParmVarDecl;
25class 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 applies.
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.
36enum class NeverCalledReason {
37  IfThen,
38  IfElse,
39  Switch,
40  SwitchSkipped,
41  LoopEntered,
42  LoopSkipped,
43  FallbackReason,
44  LARGEST_VALUE = FallbackReason
45};
46
47class CalledOnceCheckHandler {
48public:
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.
120void checkCalledOnceParameters(AnalysisDeclContext &AC,
121                               CalledOnceCheckHandler &Handler,
122                               bool CheckConventionalParameters);
123
124} // end namespace clang
125
126#endif /* LLVM_CLANG_ANALYSIS_ANALYSES_CALLEDONCECHECK_H */
127