clang  8.0.0
RetainSummaryManager.h
Go to the documentation of this file.
1 //=== RetainSummaryManager.h - Summaries for reference counting ---*- C++ -*--//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines summaries implementation for retain counting, which
11 // implements a reference count checker for Core Foundation and Cocoa
12 // on (Mac OS X).
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_CLANG_ANALYZER_CORE_RETAINSUMMARYMANAGER
17 #define LLVM_CLANG_ANALYZER_CORE_RETAINSUMMARYMANAGER
18 
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/FoldingSet.h"
21 #include "clang/AST/Attr.h"
22 #include "clang/AST/DeclCXX.h"
23 #include "clang/AST/DeclObjC.h"
24 #include "clang/AST/ParentMap.h"
27 #include "llvm/ADT/STLExtras.h"
28 
29 //===----------------------------------------------------------------------===//
30 // Adapters for FoldingSet.
31 //===----------------------------------------------------------------------===//
32 
33 using namespace clang;
34 using namespace ento;
35 
36 namespace clang {
37 namespace ento {
38 
39 /// Determines the object kind of a tracked object.
40 enum class ObjKind {
41  /// Indicates that the tracked object is a CF object.
42  CF,
43 
44  /// Indicates that the tracked object is an Objective-C object.
45  ObjC,
46 
47  /// Indicates that the tracked object could be a CF or Objective-C object.
48  AnyObj,
49 
50  /// Indicates that the tracked object is a generalized object.
52 
53  /// Indicates that the tracking object is a descendant of a
54  /// referenced-counted OSObject, used in the Darwin kernel.
55  OS
56 };
57 
59  /// There is no effect.
61 
62  /// The argument is treated as if an -autorelease message had been sent to
63  /// the referenced object.
65 
66  /// The argument is treated as if the referenced object was deallocated.
68 
69  /// The argument has its reference count decreased by 1.
71 
72  /// The argument has its reference count decreased by 1 to model
73  /// a transferred bridge cast under ARC.
75 
76  /// The argument has its reference count increased by 1.
78 
79  /// The argument is a pointer to a retain-counted object; on exit, the new
80  /// value of the pointer is a +0 value.
82 
83  /// The argument is a pointer to a retain-counted object; on exit, the new
84  /// value of the pointer is a +1 value.
86 
87  /// The argument is a pointer to a retain-counted object; on exit, the new
88  /// value of the pointer is a +1 value iff the return code is zero.
90 
91  /// The argument is a pointer to a retain-counted object; on exit, the new
92  /// value of the pointer is a +1 value iff the return code is non-zero.
94 
95  /// The argument is treated as potentially escaping, meaning that
96  /// even when its reference count hits 0 it should be treated as still
97  /// possibly being alive as someone else *may* be holding onto the object.
99 
100  /// All typestate tracking of the object ceases. This is usually employed
101  /// when the effect of the call is completely unknown.
103 
104  /// All typestate tracking of the object ceases. Unlike StopTracking,
105  /// this is also enforced when the method body is inlined.
106  ///
107  /// In some cases, we obtain a better summary for this checker
108  /// by looking at the call site than by inlining the function.
109  /// Signifies that we should stop tracking the symbol even if
110  /// the function is inlined.
112 
113  /// Performs the combined functionality of DecRef and StopTrackingHard.
114  ///
115  /// The models the effect that the called function decrements the reference
116  /// count of the argument and all typestate tracking on that argument
117  /// should cease.
119 };
120 
121 /// An ArgEffect summarizes the retain count behavior on an argument or receiver
122 /// to a function or method.
123 class ArgEffect {
124  ArgEffectKind K;
125  ObjKind O;
126 public:
128  : K(K), O(O) {}
129 
130  ArgEffectKind getKind() const { return K; }
131  ObjKind getObjKind() const { return O; }
132 
134  return ArgEffect(NewK, O);
135  }
136 
137  bool operator==(const ArgEffect &Other) const {
138  return K == Other.K && O == Other.O;
139  }
140 };
141 
142 /// RetEffect summarizes a call's retain/release behavior with respect
143 /// to its return value.
144 class RetEffect {
145 public:
146  enum Kind {
147  /// Indicates that no retain count information is tracked for
148  /// the return value.
150 
151  /// Indicates that the returned value is an owned (+1) symbol.
153 
154  /// Indicates that the returned value is an object with retain count
155  /// semantics but that it is not owned (+0). This is the default
156  /// for getters, etc.
158 
159  /// Indicates that the return value is an owned object when the
160  /// receiver is also a tracked object.
162 
163  // Treat this function as returning a non-tracked symbol even if
164  // the function has been inlined. This is used where the call
165  // site summary is more precise than the summary indirectly produced
166  // by inlining the function
167  NoRetHard
168  };
169 
170 private:
171  Kind K;
172  ObjKind O;
173 
174  RetEffect(Kind k, ObjKind o = ObjKind::AnyObj) : K(k), O(o) {}
175 
176 public:
177  Kind getKind() const { return K; }
178 
179  ObjKind getObjKind() const { return O; }
180 
181  bool isOwned() const {
182  return K == OwnedSymbol || K == OwnedWhenTrackedReceiver;
183  }
184 
185  bool notOwned() const {
186  return K == NotOwnedSymbol;
187  }
188 
189  bool operator==(const RetEffect &Other) const {
190  return K == Other.K && O == Other.O;
191  }
192 
194  return RetEffect(OwnedWhenTrackedReceiver, ObjKind::ObjC);
195  }
196 
198  return RetEffect(OwnedSymbol, o);
199  }
201  return RetEffect(NotOwnedSymbol, o);
202  }
203  static RetEffect MakeNoRet() {
204  return RetEffect(NoRet);
205  }
207  return RetEffect(NoRetHard);
208  }
209 };
210 
211 /// Encapsulates the retain count semantics on the arguments, return value,
212 /// and receiver (if any) of a function/method call.
213 ///
214 /// Note that construction of these objects is not highly efficient. That
215 /// is okay for clients where creating these objects isn't really a bottleneck.
216 /// The purpose of the API is to provide something simple. The actual
217 /// static analyzer checker that implements retain/release typestate
218 /// tracking uses something more efficient.
219 class CallEffects {
221  RetEffect Ret;
222  ArgEffect Receiver;
223 
224  CallEffects(const RetEffect &R,
226  : Ret(R), Receiver(Receiver) {}
227 
228 public:
229  /// Returns the argument effects for a call.
230  ArrayRef<ArgEffect> getArgs() const { return Args; }
231 
232  /// Returns the effects on the receiver.
233  ArgEffect getReceiver() const { return Receiver; }
234 
235  /// Returns the effect on the return value.
236  RetEffect getReturnValue() const { return Ret; }
237 
238  /// Return the CallEfect for a given Objective-C method.
239  static CallEffects getEffect(const ObjCMethodDecl *MD);
240 
241  /// Return the CallEfect for a given C/C++ function.
242  static CallEffects getEffect(const FunctionDecl *FD);
243 };
244 
245 /// A key identifying a summary.
247  IdentifierInfo* II;
248  Selector S;
249 public:
251  : II(ii), S(s) {}
252 
254  : II(d ? d->getIdentifier() : nullptr), S(s) {}
255 
257  : II(nullptr), S(s) {}
258 
259  IdentifierInfo *getIdentifier() const { return II; }
260  Selector getSelector() const { return S; }
261 };
262 
263 } // end namespace ento
264 } // end namespace clang
265 
266 
267 namespace llvm {
268 
269 template <> struct FoldingSetTrait<ArgEffect> {
270 static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) {
271  ID.AddInteger((unsigned) X.getKind());
272  ID.AddInteger((unsigned) X.getObjKind());
273 }
274 };
275 template <> struct FoldingSetTrait<RetEffect> {
276  static inline void Profile(const RetEffect &X, FoldingSetNodeID &ID) {
277  ID.AddInteger((unsigned) X.getKind());
278  ID.AddInteger((unsigned) X.getObjKind());
279 }
280 };
281 
282 template <> struct DenseMapInfo<ObjCSummaryKey> {
283  static inline ObjCSummaryKey getEmptyKey() {
286  }
287 
288  static inline ObjCSummaryKey getTombstoneKey() {
291  }
292 
293  static unsigned getHashValue(const ObjCSummaryKey &V) {
294  typedef std::pair<IdentifierInfo*, Selector> PairTy;
296  V.getSelector()));
297  }
298 
299  static bool isEqual(const ObjCSummaryKey& LHS, const ObjCSummaryKey& RHS) {
300  return LHS.getIdentifier() == RHS.getIdentifier() &&
301  LHS.getSelector() == RHS.getSelector();
302  }
303 
304 };
305 
306 } // end llvm namespace
307 
308 
309 namespace clang {
310 namespace ento {
311 
312 /// ArgEffects summarizes the effects of a function/method call on all of
313 /// its arguments.
314 typedef llvm::ImmutableMap<unsigned, ArgEffect> ArgEffects;
315 
316 /// Summary for a function with respect to ownership changes.
317 class RetainSummary {
318  /// Args - a map of (index, ArgEffect) pairs, where index
319  /// specifies the argument (starting from 0). This can be sparsely
320  /// populated; arguments with no entry in Args use 'DefaultArgEffect'.
321  ArgEffects Args;
322 
323  /// DefaultArgEffect - The default ArgEffect to apply to arguments that
324  /// do not have an entry in Args.
325  ArgEffect DefaultArgEffect;
326 
327  /// Receiver - If this summary applies to an Objective-C message expression,
328  /// this is the effect applied to the state of the receiver.
329  ArgEffect Receiver;
330 
331  /// Effect on "this" pointer - applicable only to C++ method calls.
332  ArgEffect This;
333 
334  /// Ret - The effect on the return value. Used to indicate if the
335  /// function/method call returns a new tracked symbol.
336  RetEffect Ret;
337 
338 public:
339  RetainSummary(ArgEffects A,
340  RetEffect R,
341  ArgEffect defaultEff,
342  ArgEffect ReceiverEff,
343  ArgEffect ThisEff)
344  : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff),
345  This(ThisEff), Ret(R) {}
346 
347  /// getArg - Return the argument effect on the argument specified by
348  /// idx (starting from 0).
349  ArgEffect getArg(unsigned idx) const {
350  if (const ArgEffect *AE = Args.lookup(idx))
351  return *AE;
352 
353  return DefaultArgEffect;
354  }
355 
356  void addArg(ArgEffects::Factory &af, unsigned idx, ArgEffect e) {
357  Args = af.add(Args, idx, e);
358  }
359 
360  /// setDefaultArgEffect - Set the default argument effect.
361  void setDefaultArgEffect(ArgEffect E) {
362  DefaultArgEffect = E;
363  }
364 
365  /// getRetEffect - Returns the effect on the return value of the call.
366  RetEffect getRetEffect() const { return Ret; }
367 
368  /// setRetEffect - Set the effect of the return value of the call.
369  void setRetEffect(RetEffect E) { Ret = E; }
370 
371 
372  /// Sets the effect on the receiver of the message.
373  void setReceiverEffect(ArgEffect e) { Receiver = e; }
374 
375  /// getReceiverEffect - Returns the effect on the receiver of the call.
376  /// This is only meaningful if the summary applies to an ObjCMessageExpr*.
377  ArgEffect getReceiverEffect() const { return Receiver; }
378 
379  /// \return the effect on the "this" receiver of the method call.
380  /// This is only meaningful if the summary applies to CXXMethodDecl*.
381  ArgEffect getThisEffect() const { return This; }
382 
383  /// Set the effect of the method on "this".
384  void setThisEffect(ArgEffect e) { This = e; }
385 
386  bool isNoop() const {
387  return Ret == RetEffect::MakeNoRet() && Receiver.getKind() == DoNothing
388  && DefaultArgEffect.getKind() == MayEscape && This.getKind() == DoNothing
389  && Args.isEmpty();
390  }
391 
392  /// Test if two retain summaries are identical. Note that merely equivalent
393  /// summaries are not necessarily identical (for example, if an explicit
394  /// argument effect matches the default effect).
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;
398  }
399 
400  /// Profile this summary for inclusion in a FoldingSet.
401  void Profile(llvm::FoldingSetNodeID& ID) const {
402  ID.Add(Args);
403  ID.Add(DefaultArgEffect);
404  ID.Add(Receiver);
405  ID.Add(This);
406  ID.Add(Ret);
407  }
408 
409  /// A retain summary is simple if it has no ArgEffects other than the default.
410  bool isSimple() const {
411  return Args.isEmpty();
412  }
413 
414  ArgEffects getArgEffects() const { return Args; }
415 
416 private:
417  ArgEffect getDefaultArgEffect() const { return DefaultArgEffect; }
418 
419  friend class RetainSummaryManager;
420 };
421 
422 class ObjCSummaryCache {
423  typedef llvm::DenseMap<ObjCSummaryKey, const RetainSummary *> MapTy;
424  MapTy M;
425 public:
426  ObjCSummaryCache() {}
427 
428  const RetainSummary * find(const ObjCInterfaceDecl *D, Selector S) {
429  // Do a lookup with the (D,S) pair. If we find a match return
430  // the iterator.
431  ObjCSummaryKey K(D, S);
432  MapTy::iterator I = M.find(K);
433 
434  if (I != M.end())
435  return I->second;
436  if (!D)
437  return nullptr;
438 
439  // Walk the super chain. If we find a hit with a parent, we'll end
440  // up returning that summary. We actually allow that key (null,S), as
441  // we cache summaries for the null ObjCInterfaceDecl* to allow us to
442  // generate initial summaries without having to worry about NSObject
443  // being declared.
444  // FIXME: We may change this at some point.
445  for (ObjCInterfaceDecl *C=D->getSuperClass() ;; C=C->getSuperClass()) {
446  if ((I = M.find(ObjCSummaryKey(C, S))) != M.end())
447  break;
448 
449  if (!C)
450  return nullptr;
451  }
452 
453  // Cache the summary with original key to make the next lookup faster
454  // and return the iterator.
455  const RetainSummary *Summ = I->second;
456  M[K] = Summ;
457  return Summ;
458  }
459 
460  const RetainSummary *find(IdentifierInfo* II, Selector S) {
461  // FIXME: Class method lookup. Right now we don't have a good way
462  // of going between IdentifierInfo* and the class hierarchy.
463  MapTy::iterator I = M.find(ObjCSummaryKey(II, S));
464 
465  if (I == M.end())
466  I = M.find(ObjCSummaryKey(S));
467 
468  return I == M.end() ? nullptr : I->second;
469  }
470 
471  const RetainSummary *& operator[](ObjCSummaryKey K) {
472  return M[K];
473  }
474 
475  const RetainSummary *& operator[](Selector S) {
476  return M[ ObjCSummaryKey(S) ];
477  }
478 };
479 
480 class RetainSummaryTemplate;
481 
482 class RetainSummaryManager {
483  typedef llvm::DenseMap<const FunctionDecl*, const RetainSummary *>
484  FuncSummariesTy;
485 
486  typedef ObjCSummaryCache ObjCMethodSummariesTy;
487 
488  typedef llvm::FoldingSetNodeWrapper<RetainSummary> CachedSummaryNode;
489 
490  /// Ctx - The ASTContext object for the analyzed ASTs.
491  ASTContext &Ctx;
492 
493  /// Records whether or not the analyzed code runs in ARC mode.
494  const bool ARCEnabled;
495 
496  /// Track Objective-C and CoreFoundation objects.
497  const bool TrackObjCAndCFObjects;
498 
499  /// Track sublcasses of OSObject.
500  const bool TrackOSObjects;
501 
502  /// FuncSummaries - A map from FunctionDecls to summaries.
503  FuncSummariesTy FuncSummaries;
504 
505  /// ObjCClassMethodSummaries - A map from selectors (for instance methods)
506  /// to summaries.
507  ObjCMethodSummariesTy ObjCClassMethodSummaries;
508 
509  /// ObjCMethodSummaries - A map from selectors to summaries.
510  ObjCMethodSummariesTy ObjCMethodSummaries;
511 
512  /// BPAlloc - A BumpPtrAllocator used for allocating summaries, ArgEffects,
513  /// and all other data used by the checker.
514  llvm::BumpPtrAllocator BPAlloc;
515 
516  /// AF - A factory for ArgEffects objects.
517  ArgEffects::Factory AF;
518 
519  /// ObjCAllocRetE - Default return effect for methods returning Objective-C
520  /// objects.
521  RetEffect ObjCAllocRetE;
522 
523  /// ObjCInitRetE - Default return effect for init methods returning
524  /// Objective-C objects.
525  RetEffect ObjCInitRetE;
526 
527  /// SimpleSummaries - Used for uniquing summaries that don't have special
528  /// effects.
529  llvm::FoldingSet<CachedSummaryNode> SimpleSummaries;
530 
531  /// Create an OS object at +1.
532  const RetainSummary *getOSSummaryCreateRule(const FunctionDecl *FD);
533 
534  /// Get an OS object at +0.
535  const RetainSummary *getOSSummaryGetRule(const FunctionDecl *FD);
536 
537  /// Increment the reference count on OS object.
538  const RetainSummary *getOSSummaryRetainRule(const FunctionDecl *FD);
539 
540  /// Decrement the reference count on OS object.
541  const RetainSummary *getOSSummaryReleaseRule(const FunctionDecl *FD);
542 
543  /// Free the OS object.
544  const RetainSummary *getOSSummaryFreeRule(const FunctionDecl *FD);
545 
546  const RetainSummary *getUnarySummary(const FunctionType* FT,
547  ArgEffectKind AE);
548 
549  const RetainSummary *getCFSummaryCreateRule(const FunctionDecl *FD);
550  const RetainSummary *getCFSummaryGetRule(const FunctionDecl *FD);
551  const RetainSummary *getCFCreateGetRuleSummary(const FunctionDecl *FD);
552 
553  const RetainSummary *getPersistentSummary(const RetainSummary &OldSumm);
554 
555  const RetainSummary *
556  getPersistentSummary(RetEffect RetEff, ArgEffects ScratchArgs,
557  ArgEffect ReceiverEff = ArgEffect(DoNothing),
558  ArgEffect DefaultEff = ArgEffect(MayEscape),
559  ArgEffect ThisEff = ArgEffect(DoNothing)) {
560  RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff, ThisEff);
561  return getPersistentSummary(Summ);
562  }
563 
564  const RetainSummary *getDoNothingSummary() {
565  return getPersistentSummary(RetEffect::MakeNoRet(),
566  ArgEffects(AF.getEmptyMap()),
568  }
569 
570  const RetainSummary *getDefaultSummary() {
571  return getPersistentSummary(RetEffect::MakeNoRet(),
572  ArgEffects(AF.getEmptyMap()),
574  }
575 
576  const RetainSummary *getPersistentStopSummary() {
577  return getPersistentSummary(
578  RetEffect::MakeNoRet(), ArgEffects(AF.getEmptyMap()),
580  }
581 
582  void InitializeClassMethodSummaries();
583  void InitializeMethodSummaries();
584 
585  void addNSObjectClsMethSummary(Selector S, const RetainSummary *Summ) {
586  ObjCClassMethodSummaries[S] = Summ;
587  }
588 
589  void addNSObjectMethSummary(Selector S, const RetainSummary *Summ) {
590  ObjCMethodSummaries[S] = Summ;
591  }
592 
593  void addClassMethSummary(const char* Cls, const char* name,
594  const RetainSummary *Summ, bool isNullary = true) {
595  IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
596  Selector S = isNullary ? GetNullarySelector(name, Ctx)
597  : GetUnarySelector(name, Ctx);
598  ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
599  }
600 
601  void addInstMethSummary(const char* Cls, const char* nullaryName,
602  const RetainSummary *Summ) {
603  IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
604  Selector S = GetNullarySelector(nullaryName, Ctx);
605  ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
606  }
607 
608  template <typename... Keywords>
609  void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy &Summaries,
610  const RetainSummary *Summ, Keywords *... Kws) {
611  Selector S = getKeywordSelector(Ctx, Kws...);
612  Summaries[ObjCSummaryKey(ClsII, S)] = Summ;
613  }
614 
615  template <typename... Keywords>
616  void addInstMethSummary(const char *Cls, const RetainSummary *Summ,
617  Keywords *... Kws) {
618  addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, Kws...);
619  }
620 
621  template <typename... Keywords>
622  void addClsMethSummary(const char *Cls, const RetainSummary *Summ,
623  Keywords *... Kws) {
624  addMethodSummary(&Ctx.Idents.get(Cls), ObjCClassMethodSummaries, Summ,
625  Kws...);
626  }
627 
628  template <typename... Keywords>
629  void addClsMethSummary(IdentifierInfo *II, const RetainSummary *Summ,
630  Keywords *... Kws) {
631  addMethodSummary(II, ObjCClassMethodSummaries, Summ, Kws...);
632  }
633 
634  const RetainSummary * generateSummary(const FunctionDecl *FD,
635  bool &AllowAnnotations);
636 
637  /// Return a summary for OSObject, or nullptr if not found.
638  const RetainSummary *getSummaryForOSObject(const FunctionDecl *FD,
639  StringRef FName, QualType RetTy);
640 
641  /// Return a summary for Objective-C or CF object, or nullptr if not found.
642  const RetainSummary *getSummaryForObjCOrCFObject(
643  const FunctionDecl *FD,
644  StringRef FName,
645  QualType RetTy,
646  const FunctionType *FT,
647  bool &AllowAnnotations);
648 
649  /// Apply the annotation of {@code pd} in function {@code FD}
650  /// to the resulting summary stored in out-parameter {@code Template}.
651  /// \return whether an annotation was applied.
652  bool applyParamAnnotationEffect(const ParmVarDecl *pd, unsigned parm_idx,
653  const NamedDecl *FD,
654  RetainSummaryTemplate &Template);
655 
656 public:
657  RetainSummaryManager(ASTContext &ctx,
658  bool usesARC,
659  bool trackObjCAndCFObjects,
660  bool trackOSObjects)
661  : Ctx(ctx),
662  ARCEnabled(usesARC),
663  TrackObjCAndCFObjects(trackObjCAndCFObjects),
664  TrackOSObjects(trackOSObjects),
665  AF(BPAlloc),
666  ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC)
668  ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC)
670  InitializeClassMethodSummaries();
671  InitializeMethodSummaries();
672  }
673 
674  enum class BehaviorSummary {
675  // Function does not return.
676  NoOp,
677 
678  // Function returns the first argument.
679  Identity,
680 
681  // Function either returns zero, or the input parameter.
682  IdentityOrZero
683  };
684 
685  Optional<BehaviorSummary> canEval(const CallExpr *CE, const FunctionDecl *FD,
686  bool &hasTrustedImplementationAnnotation);
687 
688  bool isTrustedReferenceCountImplementation(const FunctionDecl *FD);
689 
690  const RetainSummary *getSummary(const CallEvent &Call,
691  QualType ReceiverType=QualType());
692 
693  const RetainSummary *getFunctionSummary(const FunctionDecl *FD);
694 
695  const RetainSummary *getMethodSummary(Selector S, const ObjCInterfaceDecl *ID,
696  const ObjCMethodDecl *MD,
697  QualType RetTy,
698  ObjCMethodSummariesTy &CachedSummaries);
699 
700  const RetainSummary *
701  getInstanceMethodSummary(const ObjCMethodCall &M,
702  QualType ReceiverType);
703 
704  const RetainSummary *getClassMethodSummary(const ObjCMethodCall &M) {
705  assert(!M.isInstanceMessage());
706  const ObjCInterfaceDecl *Class = M.getReceiverInterface();
707 
708  return getMethodSummary(M.getSelector(), Class, M.getDecl(),
709  M.getResultType(), ObjCClassMethodSummaries);
710  }
711 
712  /// getMethodSummary - This version of getMethodSummary is used to query
713  /// the summary for the current method being analyzed.
714  const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD) {
715  const ObjCInterfaceDecl *ID = MD->getClassInterface();
716  Selector S = MD->getSelector();
717  QualType ResultTy = MD->getReturnType();
718 
719  ObjCMethodSummariesTy *CachedSummaries;
720  if (MD->isInstanceMethod())
721  CachedSummaries = &ObjCMethodSummaries;
722  else
723  CachedSummaries = &ObjCClassMethodSummaries;
724 
725  return getMethodSummary(S, ID, MD, ResultTy, *CachedSummaries);
726  }
727 
728  const RetainSummary *getStandardMethodSummary(const ObjCMethodDecl *MD,
729  Selector S, QualType RetTy);
730 
731  /// Determine if there is a special return effect for this function or method.
732  Optional<RetEffect> getRetEffectFromAnnotations(QualType RetTy,
733  const Decl *D);
734 
735  void updateSummaryFromAnnotations(const RetainSummary *&Summ,
736  const ObjCMethodDecl *MD);
737 
738  void updateSummaryFromAnnotations(const RetainSummary *&Summ,
739  const FunctionDecl *FD);
740 
741 
742  void updateSummaryForCall(const RetainSummary *&Summ,
743  const CallEvent &Call);
744 
745  bool isARCEnabled() const { return ARCEnabled; }
746 
747  RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
748 
749  /// Determine whether a declaration {@code D} of correspondent type (return
750  /// type for functions/methods) {@code QT} has any of the given attributes,
751  /// provided they pass necessary validation checks AND tracking the given
752  /// attribute is enabled.
753  /// Returns the object kind corresponding to the present attribute, or None,
754  /// if none of the specified attributes are present.
755  /// Crashes if passed an attribute which is not explicitly handled.
756  template <class T>
757  Optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT);
758 
759  template <class T1, class T2, class... Others>
760  Optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT);
761 
762  friend class RetainSummaryTemplate;
763 };
764 
765 
766 // Used to avoid allocating long-term (BPAlloc'd) memory for default retain
767 // summaries. If a function or method looks like it has a default summary, but
768 // it has annotations, the annotations are added to the stack-based template
769 // and then copied into managed memory.
770 class RetainSummaryTemplate {
771  RetainSummaryManager &Manager;
772  const RetainSummary *&RealSummary;
773  RetainSummary ScratchSummary;
774  bool Accessed;
775 public:
776  RetainSummaryTemplate(const RetainSummary *&real, RetainSummaryManager &mgr)
777  : Manager(mgr), RealSummary(real), ScratchSummary(*real), Accessed(false) {}
778 
779  ~RetainSummaryTemplate() {
780  if (Accessed)
781  RealSummary = Manager.getPersistentSummary(ScratchSummary);
782  }
783 
784  RetainSummary &operator*() {
785  Accessed = true;
786  return ScratchSummary;
787  }
788 
789  RetainSummary *operator->() {
790  Accessed = true;
791  return &ScratchSummary;
792  }
793 };
794 
795 } // end namespace ento
796 } // end namespace clang
797 
798 #endif
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.
Definition: Decl.h:1738
There is no effect.
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.
Definition: Type.h:638
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.cpp:1144
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...
Definition: Dominators.h:30
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:3355
All typestate tracking of the object ceases.
static RetEffect MakeOwned(ObjKind o)
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:87
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
Definition: ParentMap.cpp:23
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.
Definition: DeclObjC.h:139
Represents a parameter to a function.
Definition: Decl.h:1550
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 ...
Definition: ASTContext.h:155
IdentifierInfo * getIdentifier() const
const ObjCInterfaceDecl * getReceiverInterface() const
Get the interface for the receiver.
Definition: CallEvent.h:1034
clang::CharUnits operator*(clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU)
Definition: CharUnits.h:208
IdentifierTable & Idents
Definition: ASTContext.h:566
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.
Definition: CallEvent.h:970
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.
Definition: ASTContext.h:2953
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.
Definition: DeclObjC.h:1172
QualType getReturnType() const
Definition: DeclObjC.h:323
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
Definition: DeclObjC.cpp:338
The argument is treated as if the referenced object was deallocated.
static RetEffect MakeNotOwned(ObjKind o)
bool isInstanceMethod() const
Definition: DeclObjC.h:422
Selector getSelector() const
Definition: DeclObjC.h:321
static StringRef getIdentifier(const Token &Tok)
ArgEffectKind getKind() const
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
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
Definition: CallEvent.h:998
Selector getSelector() const
Definition: CallEvent.h:1018
Dataflow Directional Tag Classes.
static RetEffect MakeNoRetHard()
static RetEffect MakeOwnedWhenTrackedReceiver()
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:171
bool isInstanceMessage() const
Definition: CallEvent.h:1010
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 ...
Definition: SemaDecl.cpp:13954
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.
Definition: ASTContext.h:2959
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]).
Definition: Expr.h:2396
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.
Definition: Decl.h:249
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&#39;s retain/release behavior with respect to its return value.