aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/include/clang/Analysis/Analyses/CalledOnceCheck.h
diff options
context:
space:
mode:
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.h112
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 */