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