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 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. 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. handleDoubleCall(const ParmVarDecl * Parameter,const Expr * Call,const Expr * PrevCall,bool IsCompletionHandler,bool Poised)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. handleNeverCalled(const ParmVarDecl * Parameter,bool IsCompletionHandler)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. handleCapturedNeverCalled(const ParmVarDecl * Parameter,const Decl * Where,bool IsCompletionHandler)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. handleNeverCalled(const ParmVarDecl * Parameter,const Decl * Function,const Stmt * Where,NeverCalledReason Reason,bool IsCalledDirectly,bool IsCompletionHandler)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 handleBlockThatIsGuaranteedToBeCalledOnce(const BlockDecl * Block)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. handleBlockWithNoGuarantees(const BlockDecl * Block)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