summaryrefslogtreecommitdiffstats
path: root/include/clang/StaticAnalyzer/Core
diff options
context:
space:
mode:
authorJordan Rupprecht <rupprecht@google.com>2019-01-18 19:46:00 +0000
committerJordan Rupprecht <rupprecht@google.com>2019-01-18 19:46:00 +0000
commit3748d41833787fcbf59cc5624e8d2b042a8991bc (patch)
treef3fcdba7decca7ee845a1bb3f885cb0baa1b4d83 /include/clang/StaticAnalyzer/Core
parent55c8788102d8fd203270fabd6513247b2d7fbd87 (diff)
parente054eb577a1f469b1a4a49fce08572c76e2dddf2 (diff)
Creating branches/google/stable and tags/google/stable/2019-01-18 from r351319
git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/google/stable@351578 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/StaticAnalyzer/Core')
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.def6
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerRegistry.h145
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h7
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h1
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h8
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h4
-rw-r--r--include/clang/StaticAnalyzer/Core/RetainSummaryManager.h195
8 files changed, 116 insertions, 252 deletions
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
index 8e5d8d3ad3..3cd54df7b1 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
@@ -275,7 +275,7 @@ ANALYZER_OPTION(
ANALYZER_OPTION(
bool, IsNaiveCTUEnabled, "experimental-enable-naive-ctu-analysis",
"Whether naive cross translation unit analysis is enabled. This is an "
- "experimental feature to inline functions from another translation units.",
+ "experimental feature to inline functions from other translation units.",
false)
ANALYZER_OPTION(bool, ShouldDisplayMacroExpansions, "expand-macros",
@@ -344,8 +344,8 @@ ANALYZER_OPTION(StringRef, CTUDir, "ctu-dir",
"The directory containing the CTU related files.", "")
ANALYZER_OPTION(StringRef, CTUIndexName, "ctu-index-name",
- "the name of the file containing the CTU index of functions.",
- "externalFnMap.txt")
+ "the name of the file containing the CTU index of definitions.",
+ "externalDefMap.txt")
ANALYZER_OPTION(
StringRef, ModelPath, "model-path",
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
index 0e80e7bc19..d07525661a 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
@@ -16,7 +16,7 @@ namespace clang {
namespace categories {
extern const char * const CoreFoundationObjectiveC;
extern const char * const LogicError;
- extern const char * const MemoryCoreFoundationObjectiveC;
+ extern const char * const MemoryRefCount;
extern const char * const MemoryError;
extern const char * const UnixAPI;
}
diff --git a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
deleted file mode 100644
index 740754090d..0000000000
--- a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
+++ /dev/null
@@ -1,145 +0,0 @@
-//===- CheckerRegistry.h - Maintains all available checkers -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H
-#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H
-
-#include "clang/Basic/LLVM.h"
-#include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include <cstddef>
-#include <vector>
-
-// FIXME: move this information to an HTML file in docs/.
-// At the very least, a checker plugin is a dynamic library that exports
-// clang_analyzerAPIVersionString. This should be defined as follows:
-//
-// extern "C"
-// const char clang_analyzerAPIVersionString[] =
-// CLANG_ANALYZER_API_VERSION_STRING;
-//
-// This is used to check whether the current version of the analyzer is known to
-// be incompatible with a plugin. Plugins with incompatible version strings,
-// or without a version string at all, will not be loaded.
-//
-// To add a custom checker to the analyzer, the plugin must also define the
-// function clang_registerCheckers. For example:
-//
-// extern "C"
-// void clang_registerCheckers (CheckerRegistry &registry) {
-// registry.addChecker<MainCallChecker>("example.MainCallChecker",
-// "Disallows calls to functions called main");
-// }
-//
-// The first method argument is the full name of the checker, including its
-// enclosing package. By convention, the registered name of a checker is the
-// name of the associated class (the template argument).
-// The second method argument is a short human-readable description of the
-// checker.
-//
-// The clang_registerCheckers function may add any number of checkers to the
-// registry. If any checkers require additional initialization, use the three-
-// argument form of CheckerRegistry::addChecker.
-//
-// To load a checker plugin, specify the full path to the dynamic library as
-// the argument to the -load option in the cc1 frontend. You can then enable
-// your custom checker using the -analyzer-checker:
-//
-// clang -cc1 -load </path/to/plugin.dylib> -analyze
-// -analyzer-checker=<example.MainCallChecker>
-//
-// For a complete working example, see examples/analyzer-plugin.
-
-#ifndef CLANG_ANALYZER_API_VERSION_STRING
-// FIXME: The Clang version string is not particularly granular;
-// the analyzer infrastructure can change a lot between releases.
-// Unfortunately, this string has to be statically embedded in each plugin,
-// so we can't just use the functions defined in Version.h.
-#include "clang/Basic/Version.h"
-#define CLANG_ANALYZER_API_VERSION_STRING CLANG_VERSION_STRING
-#endif
-
-namespace clang {
-
-class AnalyzerOptions;
-class DiagnosticsEngine;
-
-namespace ento {
-
-/// Manages a set of available checkers for running a static analysis.
-/// The checkers are organized into packages by full name, where including
-/// a package will recursively include all subpackages and checkers within it.
-/// For example, the checker "core.builtin.NoReturnFunctionChecker" will be
-/// included if initializeManager() is called with an option of "core",
-/// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker".
-class CheckerRegistry {
-public:
- /// Initialization functions perform any necessary setup for a checker.
- /// They should include a call to CheckerManager::registerChecker.
- using InitializationFunction = void (*)(CheckerManager &);
-
- struct CheckerInfo {
- InitializationFunction Initialize;
- StringRef FullName;
- StringRef Desc;
-
- CheckerInfo(InitializationFunction fn, StringRef name, StringRef desc)
- : Initialize(fn), FullName(name), Desc(desc) {}
- };
-
- using CheckerInfoList = std::vector<CheckerInfo>;
-
-private:
- template <typename T>
- static void initializeManager(CheckerManager &mgr) {
- mgr.registerChecker<T>();
- }
-
-public:
- /// Adds a checker to the registry. Use this non-templated overload when your
- /// checker requires custom initialization.
- void addChecker(InitializationFunction fn, StringRef fullName,
- StringRef desc);
-
- /// Adds a checker to the registry. Use this templated overload when your
- /// checker does not require any custom initialization.
- template <class T>
- void addChecker(StringRef fullName, StringRef desc) {
- // Avoid MSVC's Compiler Error C2276:
- // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx
- addChecker(&CheckerRegistry::initializeManager<T>, fullName, desc);
- }
-
- /// Initializes a CheckerManager by calling the initialization functions for
- /// all checkers specified by the given CheckerOptInfo list. The order of this
- /// list is significant; later options can be used to reverse earlier ones.
- /// This can be used to exclude certain checkers in an included package.
- void initializeManager(CheckerManager &mgr, const AnalyzerOptions &Opts,
- DiagnosticsEngine &diags) const;
-
- /// Check if every option corresponds to a specific checker or package.
- void validateCheckerOptions(const AnalyzerOptions &opts,
- DiagnosticsEngine &diags) const;
-
- /// Prints the name and description of all checkers in this registry.
- /// This output is not intended to be machine-parseable.
- void printHelp(raw_ostream &out, size_t maxNameChars = 30) const;
- void printList(raw_ostream &out, const AnalyzerOptions &opts) const;
-
-private:
- mutable CheckerInfoList Checkers;
- mutable llvm::StringMap<size_t> Packages;
-};
-
-} // namespace ento
-
-} // namespace clang
-
-#endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index a53e8ee693..81dd83fc10 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -1138,9 +1138,16 @@ class CallEventManager {
public:
CallEventManager(llvm::BumpPtrAllocator &alloc) : Alloc(alloc) {}
+ /// Gets an outside caller given a callee context.
CallEventRef<>
getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State);
+ /// Gets a call event for a function call, Objective-C method call,
+ /// or a 'new' call.
+ CallEventRef<>
+ getCall(const Stmt *S, ProgramStateRef State,
+ const LocationContext *LC);
+
CallEventRef<>
getSimpleCall(const CallExpr *E, ProgramStateRef State,
const LocationContext *LCtx);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index bf01289a40..3d0ff4efa1 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -24,6 +24,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/Type.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index f544204497..c3a7028d87 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -555,15 +555,15 @@ public:
MemRegionManager& getRegionManager() {
return svalBuilder->getRegionManager();
}
- const MemRegionManager& getRegionManager() const {
+ const MemRegionManager &getRegionManager() const {
return svalBuilder->getRegionManager();
}
CallEventManager &getCallEventManager() { return *CallEventMgr; }
- StoreManager& getStoreManager() { return *StoreMgr; }
- ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
- SubEngine* getOwningEngine() { return Eng; }
+ StoreManager &getStoreManager() { return *StoreMgr; }
+ ConstraintManager &getConstraintManager() { return *ConstraintMgr; }
+ SubEngine &getOwningEngine() { return *Eng; }
ProgramStateRef removeDeadBindings(ProgramStateRef St,
const StackFrameContext *LCtx,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index 1b79bfc3f8..0efe96f67f 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -530,9 +530,7 @@ public:
return PTMDataType::getFromOpaqueValue(const_cast<void *>(Data));
}
- bool isNullMemberPointer() const {
- return getPTMData().isNull();
- }
+ bool isNullMemberPointer() const;
const DeclaratorDecl *getDecl() const;
diff --git a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
index de16a1781a..4fcaa794c1 100644
--- a/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
+++ b/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
@@ -36,9 +36,26 @@ using namespace ento;
namespace clang {
namespace ento {
-/// An ArgEffect summarizes the retain count behavior on an argument or receiver
-/// to a function or method.
-enum ArgEffect {
+/// Determines the object kind of a tracked object.
+enum class ObjKind {
+ /// Indicates that the tracked object is a CF object.
+ CF,
+
+ /// Indicates that the tracked object is an Objective-C object.
+ ObjC,
+
+ /// Indicates that the tracked object could be a CF or Objective-C object.
+ AnyObj,
+
+ /// Indicates that the tracked object is a generalized object.
+ Generalized,
+
+ /// Indicates that the tracking object is a descendant of a
+ /// referenced-counted OSObject, used in the Darwin kernel.
+ OS
+};
+
+enum ArgEffectKind {
/// There is no effect.
DoNothing,
@@ -46,44 +63,35 @@ enum ArgEffect {
/// the referenced object.
Autorelease,
- /// The argument is treated as if an -dealloc message had been sent to
- /// the referenced object.
+ /// The argument is treated as if the referenced object was deallocated.
Dealloc,
- /// The argument has its reference count decreased by 1. This is as
- /// if CFRelease has been called on the argument.
+ /// The argument has its reference count decreased by 1.
DecRef,
- /// The argument has its reference count decreased by 1. This is as
- /// if a -release message has been sent to the argument. This differs
- /// in behavior from DecRef when ARC is enabled.
- DecRefMsg,
-
/// The argument has its reference count decreased by 1 to model
/// a transferred bridge cast under ARC.
DecRefBridgedTransferred,
- /// The argument has its reference count increased by 1. This is as
- /// if a -retain message has been sent to the argument. This differs
- /// in behavior from IncRef when ARC is enabled.
- IncRefMsg,
-
- /// The argument has its reference count increased by 1. This is as
- /// if CFRetain has been called on the argument.
+ /// The argument has its reference count increased by 1.
IncRef,
- /// The argument acts as if has been passed to CFMakeCollectable, which
- /// transfers the object to the Garbage Collector under GC.
- MakeCollectable,
-
/// The argument is a pointer to a retain-counted object; on exit, the new
- /// value of the pointer is a +0 value or NULL.
+ /// value of the pointer is a +0 value.
UnretainedOutParameter,
/// The argument is a pointer to a retain-counted object; on exit, the new
- /// value of the pointer is a +1 value or NULL.
+ /// value of the pointer is a +1 value.
RetainedOutParameter,
+ /// The argument is a pointer to a retain-counted object; on exit, the new
+ /// value of the pointer is a +1 value iff the return code is zero.
+ RetainedOutParameterOnZero,
+
+ /// The argument is a pointer to a retain-counted object; on exit, the new
+ /// value of the pointer is a +1 value iff the return code is non-zero.
+ RetainedOutParameterOnNonZero,
+
/// The argument is treated as potentially escaping, meaning that
/// even when its reference count hits 0 it should be treated as still
/// possibly being alive as someone else *may* be holding onto the object.
@@ -108,13 +116,27 @@ enum ArgEffect {
/// count of the argument and all typestate tracking on that argument
/// should cease.
DecRefAndStopTrackingHard,
+};
- /// Performs the combined functionality of DecRefMsg and StopTrackingHard.
- ///
- /// The models the effect that the called function decrements the reference
- /// count of the argument and all typestate tracking on that argument
- /// should cease.
- DecRefMsgAndStopTrackingHard
+/// An ArgEffect summarizes the retain count behavior on an argument or receiver
+/// to a function or method.
+class ArgEffect {
+ ArgEffectKind K;
+ ObjKind O;
+public:
+ explicit ArgEffect(ArgEffectKind K = DoNothing, ObjKind O = ObjKind::AnyObj)
+ : K(K), O(O) {}
+
+ ArgEffectKind getKind() const { return K; }
+ ObjKind getObjKind() const { return O; }
+
+ ArgEffect withKind(ArgEffectKind NewK) {
+ return ArgEffect(NewK, O);
+ }
+
+ bool operator==(const ArgEffect &Other) const {
+ return K == Other.K && O == Other.O;
+ }
};
/// RetEffect summarizes a call's retain/release behavior with respect
@@ -125,18 +147,19 @@ public:
/// Indicates that no retain count information is tracked for
/// the return value.
NoRet,
+
/// Indicates that the returned value is an owned (+1) symbol.
OwnedSymbol,
+
/// Indicates that the returned value is an object with retain count
/// semantics but that it is not owned (+0). This is the default
/// for getters, etc.
NotOwnedSymbol,
- /// Indicates that the object is not owned and controlled by the
- /// Garbage collector.
- GCNotOwnedSymbol,
+
/// Indicates that the return value is an owned object when the
/// receiver is also a tracked object.
OwnedWhenTrackedReceiver,
+
// Treat this function as returning a non-tracked symbol even if
// the function has been inlined. This is used where the call
// site summary is more precise than the summary indirectly produced
@@ -144,27 +167,11 @@ public:
NoRetHard
};
- /// Determines the object kind of a tracked object.
- enum ObjKind {
- /// Indicates that the tracked object is a CF object. This is
- /// important between GC and non-GC code.
- CF,
- /// Indicates that the tracked object is an Objective-C object.
- ObjC,
- /// Indicates that the tracked object could be a CF or Objective-C object.
- AnyObj,
- /// Indicates that the tracked object is a generalized object.
- Generalized,
-
- /// A descendant of OSObject.
- OS
- };
-
private:
Kind K;
ObjKind O;
- RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {}
+ RetEffect(Kind k, ObjKind o = ObjKind::AnyObj) : K(k), O(o) {}
public:
Kind getKind() const { return K; }
@@ -184,7 +191,7 @@ public:
}
static RetEffect MakeOwnedWhenTrackedReceiver() {
- return RetEffect(OwnedWhenTrackedReceiver, ObjC);
+ return RetEffect(OwnedWhenTrackedReceiver, ObjKind::ObjC);
}
static RetEffect MakeOwned(ObjKind o) {
@@ -193,9 +200,6 @@ public:
static RetEffect MakeNotOwned(ObjKind o) {
return RetEffect(NotOwnedSymbol, o);
}
- static RetEffect MakeGCNotOwned() {
- return RetEffect(GCNotOwnedSymbol, ObjC);
- }
static RetEffect MakeNoRet() {
return RetEffect(NoRet);
}
@@ -217,7 +221,9 @@ class CallEffects {
RetEffect Ret;
ArgEffect Receiver;
- CallEffects(const RetEffect &R) : Ret(R) {}
+ CallEffects(const RetEffect &R,
+ ArgEffect Receiver = ArgEffect(DoNothing, ObjKind::AnyObj))
+ : Ret(R), Receiver(Receiver) {}
public:
/// Returns the argument effects for a call.
@@ -262,7 +268,8 @@ namespace llvm {
template <> struct FoldingSetTrait<ArgEffect> {
static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) {
- ID.AddInteger((unsigned) X);
+ ID.AddInteger((unsigned) X.getKind());
+ ID.AddInteger((unsigned) X.getObjKind());
}
};
template <> struct FoldingSetTrait<RetEffect> {
@@ -370,14 +377,15 @@ public:
ArgEffect getReceiverEffect() const { return Receiver; }
/// \return the effect on the "this" receiver of the method call.
+ /// This is only meaningful if the summary applies to CXXMethodDecl*.
ArgEffect getThisEffect() const { return This; }
/// Set the effect of the method on "this".
void setThisEffect(ArgEffect e) { This = e; }
bool isNoop() const {
- return Ret == RetEffect::MakeNoRet() && Receiver == DoNothing
- && DefaultArgEffect == MayEscape && This == DoNothing
+ return Ret == RetEffect::MakeNoRet() && Receiver.getKind() == DoNothing
+ && DefaultArgEffect.getKind() == MayEscape && This.getKind() == DoNothing
&& Args.isEmpty();
}
@@ -508,9 +516,6 @@ class RetainSummaryManager {
/// AF - A factory for ArgEffects objects.
ArgEffects::Factory AF;
- /// ScratchArgs - A holding buffer for construct ArgEffects.
- ArgEffects ScratchArgs;
-
/// ObjCAllocRetE - Default return effect for methods returning Objective-C
/// objects.
RetEffect ObjCAllocRetE;
@@ -523,10 +528,6 @@ class RetainSummaryManager {
/// effects.
llvm::FoldingSet<CachedSummaryNode> SimpleSummaries;
- /// getArgEffects - Returns a persistent ArgEffects object based on the
- /// data in ScratchArgs.
- ArgEffects getArgEffects();
-
/// Create an OS object at +1.
const RetainSummary *getOSSummaryCreateRule(const FunctionDecl *FD);
@@ -542,10 +543,8 @@ class RetainSummaryManager {
/// Free the OS object.
const RetainSummary *getOSSummaryFreeRule(const FunctionDecl *FD);
- enum UnaryFuncKind { cfretain, cfrelease, cfautorelease, cfmakecollectable };
-
const RetainSummary *getUnarySummary(const FunctionType* FT,
- UnaryFuncKind func);
+ ArgEffectKind AE);
const RetainSummary *getCFSummaryCreateRule(const FunctionDecl *FD);
const RetainSummary *getCFSummaryGetRule(const FunctionDecl *FD);
@@ -553,27 +552,31 @@ class RetainSummaryManager {
const RetainSummary *getPersistentSummary(const RetainSummary &OldSumm);
- const RetainSummary *getPersistentSummary(RetEffect RetEff,
- ArgEffect ReceiverEff = DoNothing,
- ArgEffect DefaultEff = MayEscape,
- ArgEffect ThisEff = DoNothing) {
- RetainSummary Summ(getArgEffects(), RetEff, DefaultEff, ReceiverEff,
- ThisEff);
+ const RetainSummary *
+ getPersistentSummary(RetEffect RetEff, ArgEffects ScratchArgs,
+ ArgEffect ReceiverEff = ArgEffect(DoNothing),
+ ArgEffect DefaultEff = ArgEffect(MayEscape),
+ ArgEffect ThisEff = ArgEffect(DoNothing)) {
+ RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff, ThisEff);
return getPersistentSummary(Summ);
}
const RetainSummary *getDoNothingSummary() {
- return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+ return getPersistentSummary(RetEffect::MakeNoRet(),
+ ArgEffects(AF.getEmptyMap()),
+ ArgEffect(DoNothing), ArgEffect(DoNothing));
}
const RetainSummary *getDefaultSummary() {
return getPersistentSummary(RetEffect::MakeNoRet(),
- DoNothing, MayEscape);
+ ArgEffects(AF.getEmptyMap()),
+ ArgEffect(DoNothing), ArgEffect(MayEscape));
}
const RetainSummary *getPersistentStopSummary() {
- return getPersistentSummary(RetEffect::MakeNoRet(),
- StopTracking, StopTracking);
+ return getPersistentSummary(
+ RetEffect::MakeNoRet(), ArgEffects(AF.getEmptyMap()),
+ ArgEffect(StopTracking), ArgEffect(StopTracking));
}
void InitializeClassMethodSummaries();
@@ -646,11 +649,9 @@ class RetainSummaryManager {
/// Apply the annotation of {@code pd} in function {@code FD}
/// to the resulting summary stored in out-parameter {@code Template}.
/// \return whether an annotation was applied.
- bool applyFunctionParamAnnotationEffect(const ParmVarDecl *pd,
- unsigned parm_idx,
- const FunctionDecl *FD,
- ArgEffects::Factory &AF,
- RetainSummaryTemplate &Template);
+ bool applyParamAnnotationEffect(const ParmVarDecl *pd, unsigned parm_idx,
+ const NamedDecl *FD,
+ RetainSummaryTemplate &Template);
public:
RetainSummaryManager(ASTContext &ctx,
@@ -661,10 +662,10 @@ public:
ARCEnabled(usesARC),
TrackObjCAndCFObjects(trackObjCAndCFObjects),
TrackOSObjects(trackOSObjects),
- AF(BPAlloc), ScratchArgs(AF.getEmptyMap()),
- ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
- : RetEffect::MakeOwned(RetEffect::ObjC)),
- ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
+ AF(BPAlloc),
+ ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC)
+ : RetEffect::MakeOwned(ObjKind::ObjC)),
+ ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC)
: RetEffect::MakeOwnedWhenTrackedReceiver()) {
InitializeClassMethodSummaries();
InitializeMethodSummaries();
@@ -745,16 +746,18 @@ public:
RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
- /// \return True if the declaration has an attribute {@code T},
- /// AND we are tracking that attribute. False otherwise.
+ /// Determine whether a declaration {@code D} of correspondent type (return
+ /// type for functions/methods) {@code QT} has any of the given attributes,
+ /// provided they pass necessary validation checks AND tracking the given
+ /// attribute is enabled.
+ /// Returns the object kind corresponding to the present attribute, or None,
+ /// if none of the specified attributes are present.
+ /// Crashes if passed an attribute which is not explicitly handled.
template <class T>
- bool hasEnabledAttr(const Decl *D) {
- return isAttrEnabled<T>() && D->hasAttr<T>();
- }
+ Optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT);
- /// Check whether we are tracking properties specified by the attributes.
- template <class T>
- bool isAttrEnabled();
+ template <class T1, class T2, class... Others>
+ Optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT);
friend class RetainSummaryTemplate;
};