1 //==-- ObjCRetainCount.h - Retain count summaries for Cocoa -------*- C++ -*--//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the core data structures for retain count "summaries"
11 // for Objective-C and Core Foundation APIs. These summaries are used
12 // by the static analyzer to summarize the retain/release effects of
13 // function and method calls. This drives a path-sensitive typestate
14 // analysis in the static analyzer, but can also potentially be used by
17 //===----------------------------------------------------------------------===//
19 #ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_OBJCRETAINCOUNT_H
20 #define LLVM_CLANG_STATICANALYZER_CHECKERS_OBJCRETAINCOUNT_H
22 #include "clang/Basic/LLVM.h"
23 #include "llvm/ADT/ArrayRef.h"
24 #include "llvm/ADT/SmallVector.h"
30 namespace ento { namespace objc_retain {
32 /// An ArgEffect summarizes the retain count behavior on an argument or receiver
33 /// to a function or method.
35 /// There is no effect.
38 /// The argument is treated as if an -autorelease message had been sent to
39 /// the referenced object.
42 /// The argument is treated as if an -dealloc message had been sent to
43 /// the referenced object.
46 /// The argument has its reference count decreased by 1. This is as
47 /// if CFRelease has been called on the argument.
50 /// The argument has its reference count decreased by 1. This is as
51 /// if a -release message has been sent to the argument. This differs
52 /// in behavior from DecRef when GC is enabled.
55 /// The argument has its reference count decreased by 1 to model
56 /// a transferred bridge cast under ARC.
57 DecRefBridgedTransferred,
59 /// The argument has its reference count increased by 1. This is as
60 /// if a -retain message has been sent to the argument. This differs
61 /// in behavior from IncRef when GC is enabled.
64 /// The argument has its reference count increased by 1. This is as
65 /// if CFRetain has been called on the argument.
68 /// The argument acts as if has been passed to CFMakeCollectable, which
69 /// transfers the object to the Garbage Collector under GC.
72 /// The argument is a pointer to a retain-counted object; on exit, the new
73 /// value of the pointer is a +0 value or NULL.
74 UnretainedOutParameter,
76 /// The argument is a pointer to a retain-counted object; on exit, the new
77 /// value of the pointer is a +1 value or NULL.
80 /// The argument is treated as potentially escaping, meaning that
81 /// even when its reference count hits 0 it should be treated as still
82 /// possibly being alive as someone else *may* be holding onto the object.
85 /// All typestate tracking of the object ceases. This is usually employed
86 /// when the effect of the call is completely unknown.
89 /// All typestate tracking of the object ceases. Unlike StopTracking,
90 /// this is also enforced when the method body is inlined.
92 /// In some cases, we obtain a better summary for this checker
93 /// by looking at the call site than by inlining the function.
94 /// Signifies that we should stop tracking the symbol even if
95 /// the function is inlined.
98 /// Performs the combined functionality of DecRef and StopTrackingHard.
100 /// The models the effect that the called function decrements the reference
101 /// count of the argument and all typestate tracking on that argument
103 DecRefAndStopTrackingHard,
105 /// Performs the combined functionality of DecRefMsg and StopTrackingHard.
107 /// The models the effect that the called function decrements the reference
108 /// count of the argument and all typestate tracking on that argument
110 DecRefMsgAndStopTrackingHard
113 /// RetEffect summarizes a call's retain/release behavior with respect
114 /// to its return value.
118 /// Indicates that no retain count information is tracked for
119 /// the return value.
121 /// Indicates that the returned value is an owned (+1) symbol.
123 /// Indicates that the returned value is an owned (+1) symbol and
124 /// that it should be treated as freshly allocated.
125 OwnedAllocatedSymbol,
126 /// Indicates that the returned value is an object with retain count
127 /// semantics but that it is not owned (+0). This is the default
128 /// for getters, etc.
130 /// Indicates that the object is not owned and controlled by the
131 /// Garbage collector.
133 /// Indicates that the return value is an owned object when the
134 /// receiver is also a tracked object.
135 OwnedWhenTrackedReceiver,
136 // Treat this function as returning a non-tracked symbol even if
137 // the function has been inlined. This is used where the call
138 // site summary is more presise than the summary indirectly produced
139 // by inlining the function
143 /// Determines the object kind of a tracked object.
145 /// Indicates that the tracked object is a CF object. This is
146 /// important between GC and non-GC code.
148 /// Indicates that the tracked object is an Objective-C object.
150 /// Indicates that the tracked object could be a CF or Objective-C object.
158 RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {}
161 Kind getKind() const { return K; }
163 ObjKind getObjKind() const { return O; }
165 bool isOwned() const {
166 return K == OwnedSymbol || K == OwnedAllocatedSymbol ||
167 K == OwnedWhenTrackedReceiver;
170 bool notOwned() const {
171 return K == NotOwnedSymbol;
174 bool operator==(const RetEffect &Other) const {
175 return K == Other.K && O == Other.O;
178 static RetEffect MakeOwnedWhenTrackedReceiver() {
179 return RetEffect(OwnedWhenTrackedReceiver, ObjC);
182 static RetEffect MakeOwned(ObjKind o, bool isAllocated = false) {
183 return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, o);
185 static RetEffect MakeNotOwned(ObjKind o) {
186 return RetEffect(NotOwnedSymbol, o);
188 static RetEffect MakeGCNotOwned() {
189 return RetEffect(GCNotOwnedSymbol, ObjC);
191 static RetEffect MakeNoRet() {
192 return RetEffect(NoRet);
194 static RetEffect MakeNoRetHard() {
195 return RetEffect(NoRetHard);
199 /// Encapsulates the retain count semantics on the arguments, return value,
200 /// and receiver (if any) of a function/method call.
202 /// Note that construction of these objects is not highly efficient. That
203 /// is okay for clients where creating these objects isn't really a bottleneck.
204 /// The purpose of the API is to provide something simple. The actual
205 /// static analyzer checker that implements retain/release typestate
206 /// tracking uses something more efficient.
208 llvm::SmallVector<ArgEffect, 10> Args;
212 CallEffects(const RetEffect &R) : Ret(R) {}
215 /// Returns the argument effects for a call.
216 ArrayRef<ArgEffect> getArgs() const { return Args; }
218 /// Returns the effects on the receiver.
219 ArgEffect getReceiver() const { return Receiver; }
221 /// Returns the effect on the return value.
222 RetEffect getReturnValue() const { return Ret; }
224 /// Return the CallEfect for a given Objective-C method.
225 static CallEffects getEffect(const ObjCMethodDecl *MD);
227 /// Return the CallEfect for a given C/C++ function.
228 static CallEffects getEffect(const FunctionDecl *FD);