15 #ifndef LLVM_CLANG_ANALYSIS_RETAINSUMMARY_MANAGER_H 16 #define LLVM_CLANG_ANALYSIS_RETAINSUMMARY_MANAGER_H 18 #include "llvm/ADT/DenseMap.h" 19 #include "llvm/ADT/FoldingSet.h" 20 #include "llvm/ADT/ImmutableMap.h" 27 #include "llvm/ADT/STLExtras.h" 29 using namespace clang;
133 return K == Other.K && O == Other.O;
177 return K == OwnedSymbol || K == OwnedWhenTrackedReceiver;
181 return K == NotOwnedSymbol;
185 return K == Other.K && O == Other.O;
218 : II(nullptr), S(s) {}
227 using namespace ento;
236 ID.AddInteger((
unsigned) X.
getKind());
242 ID.AddInteger((
unsigned) X.
getKind());
259 typedef std::pair<IdentifierInfo*, Selector> PairTy;
279 typedef llvm::ImmutableMap<unsigned, ArgEffect> ArgEffects;
282 class RetainSummary {
304 RetainSummary(ArgEffects A,
309 : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff),
315 if (
const ArgEffect *AE = Args.lookup(idx))
318 return DefaultArgEffect;
321 void addArg(ArgEffects::Factory &af,
unsigned idx,
ArgEffect e) {
322 Args = af.add(Args, idx, e);
327 DefaultArgEffect = E;
334 void setRetEffect(
RetEffect E) { Ret = E; }
338 void setReceiverEffect(
ArgEffect e) { Receiver = e; }
342 ArgEffect getReceiverEffect()
const {
return Receiver; }
348 ArgEffect getDefaultEffect()
const {
return DefaultArgEffect; }
351 void setThisEffect(
ArgEffect e) { This = e; }
353 bool isNoop()
const {
362 bool operator==(
const RetainSummary &Other)
const {
363 return Args == Other.Args && DefaultArgEffect == Other.DefaultArgEffect &&
364 Receiver == Other.Receiver && This == Other.This && Ret == Other.Ret;
368 void Profile(llvm::FoldingSetNodeID&
ID)
const {
370 ID.Add(DefaultArgEffect);
377 bool isSimple()
const {
378 return Args.isEmpty();
381 ArgEffects getArgEffects()
const {
return Args; }
384 ArgEffect getDefaultArgEffect()
const {
return DefaultArgEffect; }
386 friend class RetainSummaryManager;
389 class ObjCSummaryCache {
390 typedef llvm::DenseMap<ObjCSummaryKey, const RetainSummary *>
MapTy;
393 ObjCSummaryCache() {}
399 MapTy::iterator I = M.find(K);
422 const RetainSummary *Summ = I->second;
435 return I == M.end() ? nullptr : I->second;
442 const RetainSummary *& operator[](
Selector S) {
447 class RetainSummaryTemplate;
449 class RetainSummaryManager {
450 typedef llvm::DenseMap<const FunctionDecl*, const RetainSummary *>
453 typedef ObjCSummaryCache ObjCMethodSummariesTy;
455 typedef llvm::FoldingSetNodeWrapper<RetainSummary> CachedSummaryNode;
461 const bool ARCEnabled;
464 const bool TrackObjCAndCFObjects;
467 const bool TrackOSObjects;
470 FuncSummariesTy FuncSummaries;
474 ObjCMethodSummariesTy ObjCClassMethodSummaries;
477 ObjCMethodSummariesTy ObjCMethodSummaries;
481 llvm::BumpPtrAllocator BPAlloc;
484 ArgEffects::Factory AF;
496 llvm::FoldingSet<CachedSummaryNode> SimpleSummaries;
499 const RetainSummary *getOSSummaryCreateRule(
const FunctionDecl *FD);
502 const RetainSummary *getOSSummaryGetRule(
const FunctionDecl *FD);
505 const RetainSummary *getOSSummaryRetainRule(
const FunctionDecl *FD);
508 const RetainSummary *getOSSummaryReleaseRule(
const FunctionDecl *FD);
511 const RetainSummary *getOSSummaryFreeRule(
const FunctionDecl *FD);
513 const RetainSummary *getUnarySummary(
const FunctionType* FT,
516 const RetainSummary *getCFSummaryCreateRule(
const FunctionDecl *FD);
517 const RetainSummary *getCFSummaryGetRule(
const FunctionDecl *FD);
518 const RetainSummary *getCFCreateGetRuleSummary(
const FunctionDecl *FD);
520 const RetainSummary *getPersistentSummary(
const RetainSummary &OldSumm);
522 const RetainSummary *
523 getPersistentSummary(
RetEffect RetEff, ArgEffects ScratchArgs,
527 RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff, ThisEff);
528 return getPersistentSummary(Summ);
531 const RetainSummary *getDoNothingSummary() {
533 ArgEffects(AF.getEmptyMap()),
537 const RetainSummary *getDefaultSummary() {
539 ArgEffects(AF.getEmptyMap()),
543 const RetainSummary *getPersistentStopSummary() {
544 return getPersistentSummary(
549 void InitializeClassMethodSummaries();
550 void InitializeMethodSummaries();
552 void addNSObjectClsMethSummary(
Selector S,
const RetainSummary *Summ) {
553 ObjCClassMethodSummaries[S] = Summ;
556 void addNSObjectMethSummary(
Selector S,
const RetainSummary *Summ) {
557 ObjCMethodSummaries[S] = Summ;
560 void addClassMethSummary(
const char* Cls,
const char*
name,
561 const RetainSummary *Summ,
bool isNullary =
true) {
568 void addInstMethSummary(
const char* Cls,
const char* nullaryName,
569 const RetainSummary *Summ) {
575 template <
typename... Keywords>
576 void addMethodSummary(
IdentifierInfo *ClsII, ObjCMethodSummariesTy &Summaries,
577 const RetainSummary *Summ, Keywords *... Kws) {
582 template <
typename... Keywords>
583 void addInstMethSummary(
const char *Cls,
const RetainSummary *Summ,
585 addMethodSummary(&Ctx.
Idents.
get(Cls), ObjCMethodSummaries, Summ, Kws...);
588 template <
typename... Keywords>
589 void addClsMethSummary(
const char *Cls,
const RetainSummary *Summ,
591 addMethodSummary(&Ctx.
Idents.
get(Cls), ObjCClassMethodSummaries, Summ,
595 template <
typename... Keywords>
596 void addClsMethSummary(
IdentifierInfo *II,
const RetainSummary *Summ,
598 addMethodSummary(II, ObjCClassMethodSummaries, Summ, Kws...);
601 const RetainSummary * generateSummary(
const FunctionDecl *FD,
602 bool &AllowAnnotations);
605 const RetainSummary *getSummaryForOSObject(
const FunctionDecl *FD,
609 const RetainSummary *getSummaryForObjCOrCFObject(
614 bool &AllowAnnotations);
619 bool applyParamAnnotationEffect(
const ParmVarDecl *pd,
unsigned parm_idx,
621 RetainSummaryTemplate &Template);
624 RetainSummaryManager(
ASTContext &ctx,
bool trackObjCAndCFObjects,
626 : Ctx(ctx), ARCEnabled((
bool)Ctx.
getLangOpts().ObjCAutoRefCount),
627 TrackObjCAndCFObjects(trackObjCAndCFObjects),
628 TrackOSObjects(trackOSObjects), AF(BPAlloc),
633 InitializeClassMethodSummaries();
634 InitializeMethodSummaries();
637 enum class BehaviorSummary {
652 bool &hasTrustedImplementationAnnotation);
656 static bool isKnownSmartPointer(
QualType QT);
658 bool isTrustedReferenceCountImplementation(
const Decl *FD);
661 bool HasNonZeroCallbackArg=
false,
662 bool IsReceiverUnconsumedSelf=
false,
665 RetEffect getObjAllocRetEffect()
const {
return ObjCAllocRetE; }
673 const RetainSummary *getFunctionSummary(
const FunctionDecl *FD);
678 ObjCMethodSummariesTy &CachedSummaries);
680 const RetainSummary *
685 const RetainSummary *getStandardMethodSummary(
const ObjCMethodDecl *MD,
692 void updateSummaryFromAnnotations(
const RetainSummary *&Summ,
695 void updateSummaryFromAnnotations(
const RetainSummary *&Summ,
698 const RetainSummary *updateSummaryForNonZeroCallbackArg(
const RetainSummary *S,
713 void updateSummaryForReceiverUnconsumedSelf(
const RetainSummary *&S);
716 void updateSummaryForArgumentTypes(
const AnyCall &C,
const RetainSummary *&RS);
728 template <
class T1,
class T2,
class... Others>
731 friend class RetainSummaryTemplate;
739 class RetainSummaryTemplate {
740 RetainSummaryManager &Manager;
741 const RetainSummary *&RealSummary;
742 RetainSummary ScratchSummary;
745 RetainSummaryTemplate(
const RetainSummary *&real, RetainSummaryManager &mgr)
746 : Manager(mgr), RealSummary(real), ScratchSummary(*real), Accessed(
false) {}
748 ~RetainSummaryTemplate() {
750 RealSummary = Manager.getPersistentSummary(ScratchSummary);
755 return ScratchSummary;
758 RetainSummary *operator->() {
760 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)
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.
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...
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
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.
static RetEffect MakeNoRet()
bool This(InterpState &S, CodePtr OpPC)
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
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.
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.
bool NoRet(InterpState &S, CodePtr OpPC)
Selector getSelector() const
static const RetainSummary * getSummary(RetainSummaryManager &Summaries, const CallEvent &Call, QualType ReceiverType)
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.
An expression that sends a message to the given Objective-C object or class.
static RetEffect MakeNotOwned(ObjKind o)
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()
static bool Ret(InterpState &S, CodePtr &PC, APValue &Result)
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.
Dataflow Directional Tag Classes.
static RetEffect MakeNoRetHard()
static RetEffect MakeOwnedWhenTrackedReceiver()
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.
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...
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)
const LangOptions & getLangOpts() const
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.