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