clang 23.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.
39
40 /// Indicates that the tracked object is an Objective-C object.
42
43 /// Indicates that the tracked object could be a CF or Objective-C object.
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.
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.
140class RetEffect {
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
189 static RetEffect MakeOwnedWhenTrackedReceiver() {
190 return RetEffect(OwnedWhenTrackedReceiver, ObjKind::ObjC);
191 }
192
193 static RetEffect MakeOwned(ObjKind o) {
194 return RetEffect(OwnedSymbol, o);
195 }
196 static RetEffect MakeNotOwned(ObjKind o) {
197 return RetEffect(NotOwnedSymbol, o);
198 }
199 static RetEffect MakeNoRet() {
200 return RetEffect(NoRet);
201 }
202 static RetEffect MakeNoRetHard() {
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 unsigned getHashValue(const ObjCSummaryKey &V) {
250 typedef std::pair<IdentifierInfo*, Selector> PairTy;
251 return DenseMapInfo<PairTy>::getHashValue(PairTy(V.getIdentifier(),
252 V.getSelector()));
253 }
254
255 static bool isEqual(const ObjCSummaryKey& LHS, const ObjCSummaryKey& RHS) {
256 return LHS.getIdentifier() == RHS.getIdentifier() &&
257 LHS.getSelector() == RHS.getSelector();
258 }
259
260};
261
262} // end llvm namespace
263
264
265namespace clang {
266namespace ento {
267
268/// ArgEffects summarizes the effects of a function/method call on all of
269/// its arguments.
270typedef llvm::ImmutableMap<unsigned, ArgEffect> ArgEffects;
271
272/// Summary for a function with respect to ownership changes.
274 /// Args - a map of (index, ArgEffect) pairs, where index
275 /// specifies the argument (starting from 0). This can be sparsely
276 /// populated; arguments with no entry in Args use 'DefaultArgEffect'.
277 ArgEffects Args;
278
279 /// DefaultArgEffect - The default ArgEffect to apply to arguments that
280 /// do not have an entry in Args.
281 ArgEffect DefaultArgEffect;
282
283 /// Receiver - If this summary applies to an Objective-C message expression,
284 /// this is the effect applied to the state of the receiver.
285 ArgEffect Receiver;
286
287 /// Effect on "this" pointer - applicable only to C++ method calls.
288 ArgEffect This;
289
290 /// Ret - The effect on the return value. Used to indicate if the
291 /// function/method call returns a new tracked symbol.
292 RetEffect Ret;
293
294public:
296 RetEffect R,
297 ArgEffect defaultEff,
298 ArgEffect ReceiverEff,
299 ArgEffect ThisEff)
300 : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff),
301 This(ThisEff), Ret(R) {}
302
303 /// getArg - Return the argument effect on the argument specified by
304 /// idx (starting from 0).
305 ArgEffect getArg(unsigned idx) const {
306 if (const ArgEffect *AE = Args.lookup(idx))
307 return *AE;
308
309 return DefaultArgEffect;
310 }
311
312 void addArg(ArgEffects::Factory &af, unsigned idx, ArgEffect e) {
313 Args = af.add(Args, idx, e);
314 }
315
316 /// setDefaultArgEffect - Set the default argument effect.
318 DefaultArgEffect = E;
319 }
320
321 /// getRetEffect - Returns the effect on the return value of the call.
322 RetEffect getRetEffect() const { return Ret; }
323
324 /// setRetEffect - Set the effect of the return value of the call.
325 void setRetEffect(RetEffect E) { Ret = E; }
326
327
328 /// Sets the effect on the receiver of the message.
329 void setReceiverEffect(ArgEffect e) { Receiver = e; }
330
331 /// getReceiverEffect - Returns the effect on the receiver of the call.
332 /// This is only meaningful if the summary applies to an ObjCMessageExpr*.
333 ArgEffect getReceiverEffect() const { return Receiver; }
334
335 /// \return the effect on the "this" receiver of the method call.
336 /// This is only meaningful if the summary applies to CXXMethodDecl*.
337 ArgEffect getThisEffect() const { return This; }
338
339 ArgEffect getDefaultEffect() const { return DefaultArgEffect; }
340
341 /// Set the effect of the method on "this".
342 void setThisEffect(ArgEffect e) { This = e; }
343
344 bool isNoop() const {
345 return Ret == RetEffect::MakeNoRet() && Receiver.getKind() == DoNothing
346 && DefaultArgEffect.getKind() == MayEscape && This.getKind() == DoNothing
347 && Args.isEmpty();
348 }
349
350 /// Test if two retain summaries are identical. Note that merely equivalent
351 /// summaries are not necessarily identical (for example, if an explicit
352 /// argument effect matches the default effect).
353 bool operator==(const RetainSummary &Other) const {
354 return Args == Other.Args && DefaultArgEffect == Other.DefaultArgEffect &&
355 Receiver == Other.Receiver && This == Other.This && Ret == Other.Ret;
356 }
357
358 /// Profile this summary for inclusion in a FoldingSet.
359 void Profile(llvm::FoldingSetNodeID& ID) const {
360 ID.Add(Args);
361 ID.Add(DefaultArgEffect);
362 ID.Add(Receiver);
363 ID.Add(This);
364 ID.Add(Ret);
365 }
366
367 /// A retain summary is simple if it has no ArgEffects other than the default.
368 bool isSimple() const {
369 return Args.isEmpty();
370 }
371
372 ArgEffects getArgEffects() const { return Args; }
373
374private:
375 ArgEffect getDefaultArgEffect() const { return DefaultArgEffect; }
376
378};
379
381 typedef llvm::DenseMap<ObjCSummaryKey, const RetainSummary *> MapTy;
382 MapTy M;
383public:
385
387 // Do a lookup with the (D,S) pair. If we find a match return
388 // the iterator.
389 ObjCSummaryKey K(D, S);
390 MapTy::iterator I = M.find(K);
391
392 if (I != M.end())
393 return I->second;
394 if (!D)
395 return nullptr;
396
397 // Walk the super chain. If we find a hit with a parent, we'll end
398 // up returning that summary. We actually allow that key (null,S), as
399 // we cache summaries for the null ObjCInterfaceDecl* to allow us to
400 // generate initial summaries without having to worry about NSObject
401 // being declared.
402 // FIXME: We may change this at some point.
403 for (ObjCInterfaceDecl *C=D->getSuperClass() ;; C=C->getSuperClass()) {
404 if ((I = M.find(ObjCSummaryKey(C, S))) != M.end())
405 break;
406
407 if (!C)
408 return nullptr;
409 }
410
411 // Cache the summary with original key to make the next lookup faster
412 // and return the iterator.
413 const RetainSummary *Summ = I->second;
414 M[K] = Summ;
415 return Summ;
416 }
417
419 // FIXME: Class method lookup. Right now we don't have a good way
420 // of going between IdentifierInfo* and the class hierarchy.
421 MapTy::iterator I = M.find(ObjCSummaryKey(II, S));
422
423 if (I == M.end())
424 I = M.find(ObjCSummaryKey(S));
425
426 return I == M.end() ? nullptr : I->second;
427 }
428
430 return M[K];
431 }
432
434 return M[ ObjCSummaryKey(S) ];
435 }
436};
437
439
441 typedef llvm::DenseMap<const FunctionDecl*, const RetainSummary *>
442 FuncSummariesTy;
443
444 typedef ObjCSummaryCache ObjCMethodSummariesTy;
445
446 typedef llvm::FoldingSetNodeWrapper<RetainSummary> CachedSummaryNode;
447
448 /// Ctx - The ASTContext object for the analyzed ASTs.
449 ASTContext &Ctx;
450
451 /// Records whether or not the analyzed code runs in ARC mode.
452 const bool ARCEnabled;
453
454 /// Track Objective-C and CoreFoundation objects.
455 const bool TrackObjCAndCFObjects;
456
457 /// Track sublcasses of OSObject.
458 const bool TrackOSObjects;
459
460 /// FuncSummaries - A map from FunctionDecls to summaries.
461 FuncSummariesTy FuncSummaries;
462
463 /// ObjCClassMethodSummaries - A map from selectors (for instance methods)
464 /// to summaries.
465 ObjCMethodSummariesTy ObjCClassMethodSummaries;
466
467 /// ObjCMethodSummaries - A map from selectors to summaries.
468 ObjCMethodSummariesTy ObjCMethodSummaries;
469
470 /// BPAlloc - A BumpPtrAllocator used for allocating summaries, ArgEffects,
471 /// and all other data used by the checker.
472 llvm::BumpPtrAllocator BPAlloc;
473
474 /// AF - A factory for ArgEffects objects.
475 ArgEffects::Factory AF;
476
477 /// ObjCAllocRetE - Default return effect for methods returning Objective-C
478 /// objects.
479 RetEffect ObjCAllocRetE;
480
481 /// ObjCInitRetE - Default return effect for init methods returning
482 /// Objective-C objects.
483 RetEffect ObjCInitRetE;
484
485 /// SimpleSummaries - Used for uniquing summaries that don't have special
486 /// effects.
487 llvm::FoldingSet<CachedSummaryNode> SimpleSummaries;
488
489 /// Create an OS object at +1.
490 const RetainSummary *getOSSummaryCreateRule(const FunctionDecl *FD);
491
492 /// Get an OS object at +0.
493 const RetainSummary *getOSSummaryGetRule(const FunctionDecl *FD);
494
495 /// Increment the reference count on OS object.
496 const RetainSummary *getOSSummaryRetainRule(const FunctionDecl *FD);
497
498 /// Decrement the reference count on OS object.
499 const RetainSummary *getOSSummaryReleaseRule(const FunctionDecl *FD);
500
501 /// Free the OS object.
502 const RetainSummary *getOSSummaryFreeRule(const FunctionDecl *FD);
503
504 const RetainSummary *getUnarySummary(const FunctionType* FT,
505 ArgEffectKind AE);
506
507 const RetainSummary *getCFSummaryCreateRule(const FunctionDecl *FD);
508 const RetainSummary *getCFSummaryGetRule(const FunctionDecl *FD);
509 const RetainSummary *getCFCreateGetRuleSummary(const FunctionDecl *FD);
510
511 const RetainSummary *getPersistentSummary(const RetainSummary &OldSumm);
512
513 const RetainSummary *
514 getPersistentSummary(RetEffect RetEff, ArgEffects ScratchArgs,
515 ArgEffect ReceiverEff = ArgEffect(DoNothing),
516 ArgEffect DefaultEff = ArgEffect(MayEscape),
517 ArgEffect ThisEff = ArgEffect(DoNothing)) {
518 RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff, ThisEff);
519 return getPersistentSummary(Summ);
520 }
521
522 const RetainSummary *getDoNothingSummary() {
523 return getPersistentSummary(RetEffect::MakeNoRet(),
524 ArgEffects(AF.getEmptyMap()),
526 }
527
528 const RetainSummary *getDefaultSummary() {
529 return getPersistentSummary(RetEffect::MakeNoRet(),
530 ArgEffects(AF.getEmptyMap()),
532 }
533
534 const RetainSummary *getPersistentStopSummary() {
535 return getPersistentSummary(
536 RetEffect::MakeNoRet(), ArgEffects(AF.getEmptyMap()),
538 }
539
540 void InitializeClassMethodSummaries();
541 void InitializeMethodSummaries();
542
543 void addNSObjectClsMethSummary(Selector S, const RetainSummary *Summ) {
544 ObjCClassMethodSummaries[S] = Summ;
545 }
546
547 void addNSObjectMethSummary(Selector S, const RetainSummary *Summ) {
548 ObjCMethodSummaries[S] = Summ;
549 }
550
551 void addClassMethSummary(const char* Cls, const char* name,
552 const RetainSummary *Summ, bool isNullary = true) {
553 IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
554 Selector S = isNullary ? GetNullarySelector(name, Ctx)
555 : GetUnarySelector(name, Ctx);
556 ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
557 }
558
559 void addInstMethSummary(const char* Cls, const char* nullaryName,
560 const RetainSummary *Summ) {
561 IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
562 Selector S = GetNullarySelector(nullaryName, Ctx);
563 ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
564 }
565
566 template <typename... Keywords>
567 void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy &Summaries,
568 const RetainSummary *Summ, Keywords *... Kws) {
569 Selector S = getKeywordSelector(Ctx, Kws...);
570 Summaries[ObjCSummaryKey(ClsII, S)] = Summ;
571 }
572
573 template <typename... Keywords>
574 void addInstMethSummary(const char *Cls, const RetainSummary *Summ,
575 Keywords *... Kws) {
576 addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, Kws...);
577 }
578
579 template <typename... Keywords>
580 void addClsMethSummary(const char *Cls, const RetainSummary *Summ,
581 Keywords *... Kws) {
582 addMethodSummary(&Ctx.Idents.get(Cls), ObjCClassMethodSummaries, Summ,
583 Kws...);
584 }
585
586 template <typename... Keywords>
587 void addClsMethSummary(IdentifierInfo *II, const RetainSummary *Summ,
588 Keywords *... Kws) {
589 addMethodSummary(II, ObjCClassMethodSummaries, Summ, Kws...);
590 }
591
592 const RetainSummary * generateSummary(const FunctionDecl *FD,
593 bool &AllowAnnotations);
594
595 /// Return a summary for OSObject, or nullptr if not found.
596 const RetainSummary *getSummaryForOSObject(const FunctionDecl *FD,
597 StringRef FName, QualType RetTy);
598
599 /// Return a summary for Objective-C or CF object, or nullptr if not found.
600 const RetainSummary *getSummaryForObjCOrCFObject(
601 const FunctionDecl *FD,
602 StringRef FName,
603 QualType RetTy,
604 const FunctionType *FT,
605 bool &AllowAnnotations);
606
607 /// Apply the annotation of @c pd in function @c FD
608 /// to the resulting summary stored in out-parameter @c Template.
609 /// \return whether an annotation was applied.
610 bool applyParamAnnotationEffect(const ParmVarDecl *pd, unsigned parm_idx,
611 const NamedDecl *FD,
613
614public:
615 RetainSummaryManager(ASTContext &ctx, bool trackObjCAndCFObjects,
616 bool trackOSObjects)
617 : Ctx(ctx), ARCEnabled((bool)Ctx.getLangOpts().ObjCAutoRefCount),
618 TrackObjCAndCFObjects(trackObjCAndCFObjects),
619 TrackOSObjects(trackOSObjects), AF(BPAlloc),
620 ObjCAllocRetE(ARCEnabled ? RetEffect::MakeNotOwned(ObjKind::ObjC)
621 : RetEffect::MakeOwned(ObjKind::ObjC)),
622 ObjCInitRetE(ARCEnabled ? RetEffect::MakeNotOwned(ObjKind::ObjC)
623 : RetEffect::MakeOwnedWhenTrackedReceiver()) {
624 InitializeClassMethodSummaries();
625 InitializeMethodSummaries();
626 }
627
628 enum class BehaviorSummary {
629 // Function does not return.
631
632 // Function returns the first argument.
634
635 // Function returns "this" argument.
637
638 // Function either returns zero, or the input parameter.
640 };
641
642 std::optional<BehaviorSummary>
643 canEval(const CallExpr *CE, const FunctionDecl *FD,
644 bool &hasTrustedImplementationAnnotation);
645
646 /// \return Whether the type corresponds to a known smart pointer
647 /// implementation (that is, everything about it is inlineable).
648 static bool isKnownSmartPointer(QualType QT);
649
651
653 bool HasNonZeroCallbackArg=false,
654 bool IsReceiverUnconsumedSelf=false,
655 QualType ReceiverType={});
656
657 RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
658
659private:
660
661 /// getMethodSummary - This version of getMethodSummary is used to query
662 /// the summary for the current method being analyzed.
663 const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD);
664
665 const RetainSummary *getFunctionSummary(const FunctionDecl *FD);
666
667 const RetainSummary *getMethodSummary(Selector S, const ObjCInterfaceDecl *ID,
668 const ObjCMethodDecl *MD,
669 QualType RetTy,
670 ObjCMethodSummariesTy &CachedSummaries);
671
672 const RetainSummary *
673 getInstanceMethodSummary(const ObjCMessageExpr *ME, QualType ReceiverType);
674
675 const RetainSummary *getClassMethodSummary(const ObjCMessageExpr *ME);
676
677 const RetainSummary *getStandardMethodSummary(const ObjCMethodDecl *MD,
678 Selector S, QualType RetTy);
679
680 /// Determine if there is a special return effect for this function or method.
681 std::optional<RetEffect> getRetEffectFromAnnotations(QualType RetTy,
682 const Decl *D);
683
684 void updateSummaryFromAnnotations(const RetainSummary *&Summ,
685 const ObjCMethodDecl *MD);
686
687 void updateSummaryFromAnnotations(const RetainSummary *&Summ,
688 const FunctionDecl *FD);
689
690 const RetainSummary *updateSummaryForNonZeroCallbackArg(const RetainSummary *S,
691 AnyCall &C);
692
693 /// Special case '[super init];' and '[self init];'
694 ///
695 /// Even though calling '[super init]' without assigning the result to self
696 /// and checking if the parent returns 'nil' is a bad pattern, it is common.
697 /// Additionally, our Self Init checker already warns about it. To avoid
698 /// overwhelming the user with messages from both checkers, we model the case
699 /// of '[super init]' in cases when it is not consumed by another expression
700 /// as if the call preserves the value of 'self'; essentially, assuming it can
701 /// never fail and return 'nil'.
702 /// Note, we don't want to just stop tracking the value since we want the
703 /// RetainCount checker to report leaks and use-after-free if SelfInit checker
704 /// is turned off.
705 void updateSummaryForReceiverUnconsumedSelf(const RetainSummary *&S);
706
707 /// Set argument types for arguments which are not doing anything.
708 void updateSummaryForArgumentTypes(const AnyCall &C, const RetainSummary *&RS);
709
710 /// Determine whether a declaration @c D of correspondent type (return
711 /// type for functions/methods) @c QT has any of the given attributes,
712 /// provided they pass necessary validation checks AND tracking the given
713 /// attribute is enabled.
714 /// Returns the object kind corresponding to the present attribute, or
715 /// std::nullopt, if none of the specified attributes are present.
716 /// Crashes if passed an attribute which is not explicitly handled.
717 template <class T>
718 std::optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT);
719
720 template <class T1, class T2, class... Others>
721 std::optional<ObjKind> hasAnyEnabledAttrOf(const Decl *D, QualType QT);
722
724};
725
726
727// Used to avoid allocating long-term (BPAlloc'd) memory for default retain
728// summaries. If a function or method looks like it has a default summary, but
729// it has annotations, the annotations are added to the stack-based template
730// and then copied into managed memory.
732 RetainSummaryManager &Manager;
733 const RetainSummary *&RealSummary;
734 RetainSummary ScratchSummary;
735 bool Accessed;
736public:
738 : Manager(mgr), RealSummary(real), ScratchSummary(*real), Accessed(false) {}
739
741 if (Accessed)
742 RealSummary = Manager.getPersistentSummary(ScratchSummary);
743 }
744
746 Accessed = true;
747 return ScratchSummary;
748 }
749
751 Accessed = true;
752 return &ScratchSummary;
753 }
754};
755
756} // end namespace ento
757} // end namespace clang
758
759#endif
#define V(N, I)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
#define X(type, name)
Definition Value.h:97
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
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:2946
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
Represents a function declaration or definition.
Definition Decl.h:2018
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition TypeBase.h:4565
One of these records is kept for each identifier that is lexed.
This represents a decl that may have a name.
Definition Decl.h:274
Represents an ObjC class declaration.
Definition DeclObjC.h:1154
ObjCInterfaceDecl * getSuperClass() const
Definition DeclObjC.cpp:349
An expression that sends a message to the given Objective-C object or class.
Definition ExprObjC.h:971
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
Represents a parameter to a function.
Definition Decl.h:1808
A (possibly-)qualified type.
Definition TypeBase.h:937
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 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)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
Selector GetUnarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing an unary selector.
@ Template
We are parsing a template declaration.
Definition Parser.h:81
Selector GetNullarySelector(StringRef name, ASTContext &Ctx)
Utility function for constructing a nullary selector.
@ Other
Other implicit parameter.
Definition Decl.h:1763
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
#define false
Definition stdbool.h:26
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)