Home | History | Annotate | Line # | Download | only in Analyses
      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 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,
     41   SwitchSkipped,
     42   LoopEntered,
     43   LoopSkipped,
     44   FallbackReason,
     45   LARGEST_VALUE = FallbackReason
     46 };
     47 
     48 class CalledOnceCheckHandler {
     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
    100   handleBlockThatIsGuaranteedToBeCalledOnce(const BlockDecl *Block) {}
    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 */
    128