clang 20.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"
27#include "llvm/ADT/STLExtras.h"
28#include <optional>
29
30using namespace clang;
31
32namespace clang {
33namespace ento {
34
35/// Determines the object kind of a tracked object.
36enum 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.
121 ObjKind O;
122public:
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.
141public:
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
164 };
165
166private:
167 Kind K;
168 ObjKind O;
169
170 RetEffect(Kind k, ObjKind o = ObjKind::AnyObj) : K(k), O(o) {}
171
172public:
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 }
200 return RetEffect(NoRet);
201 }
203 return RetEffect(NoRetHard);
204 }
205};
206
207/// A key identifying a summary.
209 IdentifierInfo* II;
210 Selector S;
211public:
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
228using namespace ento;
229
230namespace llvm {
231
232//===----------------------------------------------------------------------===//
233// Adapters for FoldingSet.
234//===----------------------------------------------------------------------===//
235template <> struct FoldingSetTrait<ArgEffect> {
236static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) {
237 ID.AddInteger((unsigned) X.getKind());
238 ID.AddInteger((unsigned) X.getObjKind());
239}
240};
241template <> 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
248template <> struct DenseMapInfo<ObjCSummaryKey> {
249 static inline ObjCSummaryKey getEmptyKey() {
250 return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getEmptyKey(),
251 DenseMapInfo<Selector>::getEmptyKey());
252 }
253
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
275namespace clang {
276namespace ento {
277
278/// ArgEffects summarizes the effects of a function/method call on all of
279/// its arguments.
280typedef 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
304public:
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
384private:
385 ArgEffect getDefaultArgEffect() const { return DefaultArgEffect; }
386
388};
389
391 typedef llvm::DenseMap<ObjCSummaryKey, const RetainSummary *> MapTy;
392 MapTy M;
393public:
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
624public:
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.
647
648 // Function either returns zero, or the input parameter.
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
661
663 bool HasNonZeroCallbackArg=false,
664 bool IsReceiverUnconsumedSelf=false,
665 QualType ReceiverType={});
666
667 RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
668
669private:
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
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;
746public:
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:3341
const Decl * D
Expr * E
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
#define X(type, name)
Definition: Value.h:143
__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:187
IdentifierTable & Idents
Definition: ASTContext.h:660
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:2830
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
Represents a function declaration or definition.
Definition: Decl.h:1932
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4308
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
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:1722
A (possibly-)qualified type.
Definition: Type.h:941
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 * find(const ObjCInterfaceDecl *D, Selector S)
const RetainSummary *& operator[](Selector S)
const RetainSummary * find(IdentifierInfo *II, Selector S)
const RetainSummary *& operator[](ObjCSummaryKey K)
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
bool isTrustedReferenceCountImplementation(const Decl *FD)
std::optional< BehaviorSummary > canEval(const CallExpr *CE, const FunctionDecl *FD, bool &hasTrustedImplementationAnnotation)
static bool isKnownSmartPointer(QualType QT)
const RetainSummary * getSummary(AnyCall C, bool HasNonZeroCallbackArg=false, bool IsReceiverUnconsumedSelf=false, QualType ReceiverType={})
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.
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:3496
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
Definition: ASTContext.h:3490
@ 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)