diff options
Diffstat (limited to 'contrib/llvm-project/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h')
-rw-r--r-- | contrib/llvm-project/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/contrib/llvm-project/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h new file mode 100644 index 000000000000..fc574c680a44 --- /dev/null +++ b/contrib/llvm-project/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h @@ -0,0 +1,112 @@ +//===- CalledOnceCheck.h - Check 'called once' parameters -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines a check for function-like parameters that should be +// called exactly one time. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_CALLEDONCECHECK_H +#define LLVM_CLANG_ANALYSIS_ANALYSES_CALLEDONCECHECK_H + +namespace clang { + +class AnalysisDeclContext; +class CFG; +class Decl; +class DeclContext; +class Expr; +class ParmVarDecl; +class Stmt; + +/// Classification of situations when parameter is not called on every path. +/// \enum IfThen -- then branch of the if statement has no call. +/// \enum IfElse -- else branch of the if statement has no call. +/// \enum Switch -- one of the switch cases doesn't have a call. +/// \enum SwitchSkipped -- there is no call if none of the cases appies. +/// \enum LoopEntered -- no call when the loop is entered. +/// \enum LoopSkipped -- no call when the loop is not entered. +/// \enum FallbackReason -- fallback case when we were not able to figure out +/// the reason. +enum class NeverCalledReason { + IfThen, + IfElse, + Switch, + SwitchSkipped, + LoopEntered, + LoopSkipped, + FallbackReason, + LARGEST_VALUE = FallbackReason +}; + +class CalledOnceCheckHandler { +public: + CalledOnceCheckHandler() = default; + virtual ~CalledOnceCheckHandler() = default; + + /// Called when parameter is called twice. + /// \param Parameter -- parameter that should be called once. + /// \param Call -- call to report the warning. + /// \param PrevCall -- previous call. + /// \param IsCompletionHandler -- true, if parameter is a completion handler. + /// \param Poised -- true, if the second call is guaranteed to happen after + /// the first call. + virtual void handleDoubleCall(const ParmVarDecl *Parameter, const Expr *Call, + const Expr *PrevCall, bool IsCompletionHandler, + bool Poised) {} + + /// Called when parameter is not called at all. + /// \param Parameter -- parameter that should be called once. + /// \param IsCompletionHandler -- true, if parameter is a completion handler. + virtual void handleNeverCalled(const ParmVarDecl *Parameter, + bool IsCompletionHandler) {} + + /// Called when captured parameter is not called at all. + /// \param Parameter -- parameter that should be called once. + /// \param Where -- declaration that captures \p Parameter + /// \param IsCompletionHandler -- true, if parameter is a completion handler. + virtual void handleCapturedNeverCalled(const ParmVarDecl *Parameter, + const Decl *Where, + bool IsCompletionHandler) {} + + /// Called when parameter is not called on one of the paths. + /// Usually we try to find a statement that is the least common ancestor of + /// the path containing the call and not containing the call. This helps us + /// to pinpoint a bad path for the user. + /// \param Parameter -- parameter that should be called once. + /// \param Where -- the least common ancestor statement. + /// \param Reason -- a reason describing the path without a call. + /// \param IsCalledDirectly -- true, if parameter actually gets called on + /// the other path. It is opposed to be used in some other way (added to some + /// collection, passed as a parameter, etc.). + /// \param IsCompletionHandler -- true, if parameter is a completion handler. + virtual void handleNeverCalled(const ParmVarDecl *Parameter, + const Stmt *Where, NeverCalledReason Reason, + bool IsCalledDirectly, + bool IsCompletionHandler) {} +}; + +/// Check given CFG for 'called once' parameter violations. +/// +/// It traverses the function and tracks how such parameters are used. +/// It detects two main violations: +/// * parameter is called twice +/// * parameter is not called +/// +/// \param AC -- context. +/// \param Handler -- a handler for found violations. +/// \param CheckConventionalParameters -- true, if we want to check parameters +/// not explicitly marked as 'called once', but having the same requirements +/// according to conventions. +void checkCalledOnceParameters(AnalysisDeclContext &AC, + CalledOnceCheckHandler &Handler, + bool CheckConventionalParameters); + +} // end namespace clang + +#endif /* LLVM_CLANG_ANALYSIS_ANALYSES_CALLEDONCECHECK_H */ |