16 #ifndef LLVM_CLANG_ANALYZER_CORE_RETAINSUMMARYMANAGER 17 #define LLVM_CLANG_ANALYZER_CORE_RETAINSUMMARYMANAGER 19 #include "llvm/ADT/DenseMap.h" 20 #include "llvm/ADT/FoldingSet.h" 27 #include "llvm/ADT/STLExtras.h" 33 using namespace clang;
138 return K == Other.K && O == Other.O;
182 return K == OwnedSymbol || K == OwnedWhenTrackedReceiver;
186 return K == NotOwnedSymbol;
190 return K == Other.K && O == Other.O;
226 : Ret(R), Receiver(Receiver) {}
257 : II(nullptr), S(s) {}
271 ID.AddInteger((
unsigned) X.
getKind());
277 ID.AddInteger((
unsigned) X.
getKind());
294 typedef std::pair<IdentifierInfo*, Selector> PairTy;
314 typedef llvm::ImmutableMap<unsigned, ArgEffect> ArgEffects;
317 class RetainSummary {
339 RetainSummary(ArgEffects A,
344 : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff),
345 This(ThisEff), Ret(R) {}
350 if (
const ArgEffect *AE = Args.lookup(idx))
353 return DefaultArgEffect;
356 void addArg(ArgEffects::Factory &af,
unsigned idx,
ArgEffect e) {
357 Args = af.add(Args, idx, e);
362 DefaultArgEffect = E;
366 RetEffect getRetEffect()
const {
return Ret; }
369 void setRetEffect(
RetEffect E) { Ret = E; }
373 void setReceiverEffect(
ArgEffect e) { Receiver = e; }
377 ArgEffect getReceiverEffect()
const {
return Receiver; }
381 ArgEffect getThisEffect()
const {
return This; }
384 void setThisEffect(
ArgEffect e) { This = e; }
386 bool isNoop()
const {
395 bool operator==(
const RetainSummary &Other)
const {
396 return Args == Other.Args && DefaultArgEffect == Other.DefaultArgEffect &&
397 Receiver == Other.Receiver && This == Other.This && Ret == Other.Ret;
401 void Profile(llvm::FoldingSetNodeID&
ID)
const {
403 ID.Add(DefaultArgEffect);
410 bool isSimple()
const {
411 return Args.isEmpty();
414 ArgEffects getArgEffects()
const {
return Args; }
417 ArgEffect getDefaultArgEffect()
const {
return DefaultArgEffect; }
419 friend class RetainSummaryManager;
422 class ObjCSummaryCache {
423 typedef llvm::DenseMap<ObjCSummaryKey, const RetainSummary *>
MapTy;
426 ObjCSummaryCache() {}
432 MapTy::iterator I = M.find(K);
455 const RetainSummary *Summ = I->second;
468 return I == M.end() ? nullptr : I->second;
475 const RetainSummary *& operator[](
Selector S) {
480 class RetainSummaryTemplate;
482 class RetainSummaryManager {
483 typedef llvm::DenseMap<const FunctionDecl*, const RetainSummary *>
486 typedef ObjCSummaryCache ObjCMethodSummariesTy;
488 typedef llvm::FoldingSetNodeWrapper<RetainSummary> CachedSummaryNode;
494 const bool ARCEnabled;
497 const bool TrackObjCAndCFObjects;
500 const bool TrackOSObjects;
503 FuncSummariesTy FuncSummaries;
507 ObjCMethodSummariesTy ObjCClassMethodSummaries;
510 ObjCMethodSummariesTy ObjCMethodSummaries;
514 llvm::BumpPtrAllocator BPAlloc;
517 ArgEffects::Factory AF;
529 llvm::FoldingSet<CachedSummaryNode> SimpleSummaries;
532 const RetainSummary *getOSSummaryCreateRule(
const FunctionDecl *FD);
535 const RetainSummary *getOSSummaryGetRule(
const FunctionDecl *FD);
538 const RetainSummary *getOSSummaryRetainRule(
const FunctionDecl *FD);
541 const RetainSummary *getOSSummaryReleaseRule(
const FunctionDecl *FD);
544 const RetainSummary *getOSSummaryFreeRule(
const FunctionDecl *FD);
546 const RetainSummary *getUnarySummary(
const FunctionType* FT,
549 const RetainSummary *getCFSummaryCreateRule(
const FunctionDecl *FD);
550 const RetainSummary *getCFSummaryGetRule(
const FunctionDecl *FD);
551 const RetainSummary *getCFCreateGetRuleSummary(
const FunctionDecl *FD);
553 const RetainSummary *getPersistentSummary(
const RetainSummary &OldSumm);
555 const RetainSummary *
556 getPersistentSummary(
RetEffect RetEff, ArgEffects ScratchArgs,
560 RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff, ThisEff);
561 return getPersistentSummary(Summ);
564 const RetainSummary *getDoNothingSummary() {
566 ArgEffects(AF.getEmptyMap()),
570 const RetainSummary *getDefaultSummary() {
572 ArgEffects(AF.getEmptyMap()),
576 const RetainSummary *getPersistentStopSummary() {
577 return getPersistentSummary(
582 void InitializeClassMethodSummaries();
583 void InitializeMethodSummaries();
585 void addNSObjectClsMethSummary(
Selector S,
const RetainSummary *Summ) {
586 ObjCClassMethodSummaries[S] = Summ;
589 void addNSObjectMethSummary(
Selector S,
const RetainSummary *Summ) {
590 ObjCMethodSummaries[S] = Summ;
593 void addClassMethSummary(
const char* Cls,
const char* name,
594 const RetainSummary *Summ,
bool isNullary =
true) {
601 void addInstMethSummary(
const char* Cls,
const char* nullaryName,
602 const RetainSummary *Summ) {
608 template <
typename... Keywords>
609 void addMethodSummary(
IdentifierInfo *ClsII, ObjCMethodSummariesTy &Summaries,
610 const RetainSummary *Summ, Keywords *... Kws) {
615 template <
typename... Keywords>
616 void addInstMethSummary(
const char *Cls,
const RetainSummary *Summ,
618 addMethodSummary(&Ctx.
Idents.
get(Cls), ObjCMethodSummaries, Summ, Kws...);
621 template <
typename... Keywords>
622 void addClsMethSummary(
const char *Cls,
const RetainSummary *Summ,
624 addMethodSummary(&Ctx.
Idents.
get(Cls), ObjCClassMethodSummaries, Summ,
628 template <
typename... Keywords>
629 void addClsMethSummary(
IdentifierInfo *II,
const RetainSummary *Summ,
631 addMethodSummary(II, ObjCClassMethodSummaries, Summ, Kws...);
634 const RetainSummary * generateSummary(
const FunctionDecl *FD,
635 bool &AllowAnnotations);
638 const RetainSummary *getSummaryForOSObject(
const FunctionDecl *FD,
642 const RetainSummary *getSummaryForObjCOrCFObject(
647 bool &AllowAnnotations);
652 bool applyParamAnnotationEffect(
const ParmVarDecl *pd,
unsigned parm_idx,
654 RetainSummaryTemplate &Template);
659 bool trackObjCAndCFObjects,
663 TrackObjCAndCFObjects(trackObjCAndCFObjects),
664 TrackOSObjects(trackOSObjects),
670 InitializeClassMethodSummaries();
671 InitializeMethodSummaries();
674 enum class BehaviorSummary {
686 bool &hasTrustedImplementationAnnotation);
688 bool isTrustedReferenceCountImplementation(
const FunctionDecl *FD);
690 const RetainSummary *getSummary(
const CallEvent &Call,
693 const RetainSummary *getFunctionSummary(
const FunctionDecl *FD);
698 ObjCMethodSummariesTy &CachedSummaries);
700 const RetainSummary *
704 const RetainSummary *getClassMethodSummary(
const ObjCMethodCall &M) {
709 M.getResultType(), ObjCClassMethodSummaries);
719 ObjCMethodSummariesTy *CachedSummaries;
721 CachedSummaries = &ObjCMethodSummaries;
723 CachedSummaries = &ObjCClassMethodSummaries;
725 return getMethodSummary(S, ID, MD, ResultTy, *CachedSummaries);
728 const RetainSummary *getStandardMethodSummary(
const ObjCMethodDecl *MD,
735 void updateSummaryFromAnnotations(
const RetainSummary *&Summ,
738 void updateSummaryFromAnnotations(
const RetainSummary *&Summ,
742 void updateSummaryForCall(
const RetainSummary *&Summ,
745 bool isARCEnabled()
const {
return ARCEnabled; }
747 RetEffect getObjAllocRetEffect()
const {
return ObjCAllocRetE; }
759 template <
class T1,
class T2,
class... Others>
762 friend class RetainSummaryTemplate;
770 class RetainSummaryTemplate {
771 RetainSummaryManager &Manager;
772 const RetainSummary *&RealSummary;
773 RetainSummary ScratchSummary;
776 RetainSummaryTemplate(
const RetainSummary *&real, RetainSummaryManager &mgr)
777 : Manager(mgr), RealSummary(real), ScratchSummary(*real), Accessed(
false) {}
779 ~RetainSummaryTemplate() {
781 RealSummary = Manager.getPersistentSummary(ScratchSummary);
786 return ScratchSummary;
789 RetainSummary *operator->() {
791 return &ScratchSummary;
Indicates that the tracked object is a generalized object.
Indicates that the tracked object is a CF object.
ObjCSummaryKey(const ObjCInterfaceDecl *d, Selector s)
Encapsulates the retain count semantics on the arguments, return value, and receiver (if any) of a fu...
Represents a function declaration or definition.
Smart pointer class that efficiently represents Objective-C method names.
ObjKind
Determines the object kind of a tracked object.
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
A (possibly-)qualified type.
ObjCInterfaceDecl * getClassInterface()
ArgEffect(ArgEffectKind K=DoNothing, ObjKind O=ObjKind::AnyObj)
bool operator==(CanQual< T > x, CanQual< U > y)
Indicates that the tracked object could be a CF or Objective-C object.
The argument has its reference count decreased by 1 to model a transferred bridge cast under ARC...
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
FunctionType - C99 6.7.5.3 - Function Declarators.
All typestate tracking of the object ceases.
static RetEffect MakeOwned(ObjKind o)
ObjKind getObjKind() const
Decl - This represents one declaration (or definition), e.g.
The argument has its reference count increased by 1.
The argument is treated as if an -autorelease message had been sent to the referenced object...
llvm::DenseMap< Stmt *, Stmt * > MapTy
Indicates that no retain count information is tracked for the return value.
ArrayRef< ArgEffect > getArgs() const
Returns the argument effects for a call.
static RetEffect MakeNoRet()
ObjCMethodDecl - Represents an instance or class method declaration.
ObjKind getObjKind() const
Represents a parameter to a function.
One of these records is kept for each identifier that is lexed.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
IdentifierInfo * getIdentifier() const
const ObjCInterfaceDecl * getReceiverInterface() const
Get the interface for the receiver.
clang::CharUnits operator*(clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU)
static ObjCSummaryKey getTombstoneKey()
static bool isEqual(const ObjCSummaryKey &LHS, const ObjCSummaryKey &RHS)
bool operator==(const ArgEffect &Other) const
The argument has its reference count decreased by 1.
Represents any expression that calls an Objective-C method.
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +0 v...
static void Profile(const ArgEffect X, FoldingSetNodeID &ID)
Indicates that the return value is an owned object when the receiver is also a tracked object...
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
Represents an ObjC class declaration.
QualType getReturnType() const
Selector getSelector() const
The argument is treated as potentially escaping, meaning that even when its reference count hits 0 it...
ObjCSummaryKey(IdentifierInfo *ii, Selector s)
ObjCInterfaceDecl * getSuperClass() const
The argument is treated as if the referenced object was deallocated.
static RetEffect MakeNotOwned(ObjKind o)
bool isInstanceMethod() const
Selector getSelector() const
static StringRef getIdentifier(const Token &Tok)
ArgEffectKind getKind() const
ObjCSummaryKey(Selector s)
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static ObjCSummaryKey getEmptyKey()
Indicates that the tracked object is an Objective-C object.
static void Profile(const RetEffect &X, FoldingSetNodeID &ID)
Performs the combined functionality of DecRef and StopTrackingHard.
static Selector getKeywordSelector(ASTContext &Ctx, IdentifierInfos *... IIs)
A key identifying a summary.
const ObjCMethodDecl * getDecl() const override
Selector getSelector() const
Dataflow Directional Tag Classes.
static RetEffect MakeNoRetHard()
static RetEffect MakeOwnedWhenTrackedReceiver()
Represents an abstract call to a function or method along a particular path.
bool isInstanceMessage() const
Indicates that the tracking object is a descendant of a referenced-counted OSObject, used in the Darwin kernel.
bool operator==(const RetEffect &Other) const
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
ArgEffect withKind(ArgEffectKind NewK)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
All typestate tracking of the object ceases.
Indicates that the returned value is an owned (+1) symbol.
ArgEffect getReceiver() const
Returns the effects on the receiver.
Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
RetEffect getReturnValue() const
Returns the effect on the return value.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
The argument is a pointer to a retain-counted object; on exit, the new value of the pointer is a +1 v...
An ArgEffect summarizes the retain count behavior on an argument or receiver to a function or method...
This represents a decl that may have a name.
static unsigned getHashValue(const ObjCSummaryKey &V)
Indicates that the returned value is an object with retain count semantics but that it is not owned (...
RetEffect summarizes a call's retain/release behavior with respect to its return value.