15774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek//==-- ObjCRetainCount.h - Retain count summaries for Cocoa -------*- C++ -*--//
25774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek//
35774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek//                     The LLVM Compiler Infrastructure
45774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek//
55774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek// This file is distributed under the University of Illinois Open Source
65774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek// License. See LICENSE.TXT for details.
75774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek//
85774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek//===----------------------------------------------------------------------===//
95774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek//
105774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek//  This file defines the core data structures for retain count "summaries"
115774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek//  for Objective-C and Core Foundation APIs.  These summaries are used
125774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek//  by the static analyzer to summarize the retain/release effects of
135774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek//  function and method calls.  This drives a path-sensitive typestate
145774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek//  analysis in the static analyzer, but can also potentially be used by
155774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek//  other clients.
165774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek//
175774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek//===----------------------------------------------------------------------===//
185774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
195774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek#ifndef LLVM_CLANG_OBJCRETAINCOUNT_H
205774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek#define LLVM_CLANG_OBJCRETAINCOUNT_H
215774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
225774e390199a572d10b22c78a80ed2cdde94304dTed Kremeneknamespace clang { namespace ento { namespace objc_retain {
235774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
245774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek/// An ArgEffect summarizes the retain count behavior on an argument or receiver
255774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek/// to a function or method.
265774e390199a572d10b22c78a80ed2cdde94304dTed Kremenekenum ArgEffect {
275774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// There is no effect.
285774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  DoNothing,
295774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
305774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// The argument is treated as if an -autorelease message had been sent to
315774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// the referenced object.
325774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  Autorelease,
335774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
345774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// The argument is treated as if an -dealloc message had been sent to
355774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// the referenced object.
365774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  Dealloc,
375774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
385774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// The argument has its reference count decreased by 1.  This is as
395774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// if CFRelease has been called on the argument.
405774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  DecRef,
415774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
425774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// The argument has its reference count decreased by 1.  This is as
435774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// if a -release message has been sent to the argument.  This differs
445774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// in behavior from DecRef when GC is enabled.
455774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  DecRefMsg,
465774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
475774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// The argument has its reference count decreased by 1 to model
485774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// a transferred bridge cast under ARC.
49063820655db8121f0022a7c51458463c7250324cBenjamin Kramer  DecRefBridgedTransferred,
505774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
515774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// The argument has its reference count increased by 1.  This is as
525774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// if a -retain message has been sent to the argument.  This differs
535774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// in behavior from IncRef when GC is enabled.
545774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  IncRefMsg,
555774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
565774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// The argument has its reference count increased by 1.  This is as
575774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// if CFRetain has been called on the argument.
585774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  IncRef,
595774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
605774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// The argument acts as if has been passed to CFMakeCollectable, which
615774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// transfers the object to the Garbage Collector under GC.
625774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  MakeCollectable,
635774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
645774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// The argument is treated as potentially escaping, meaning that
655774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// even when its reference count hits 0 it should be treated as still
665774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// possibly being alive as someone else *may* be holding onto the object.
675774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  MayEscape,
685774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
695774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// All typestate tracking of the object ceases.  This is usually employed
705774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// when the effect of the call is completely unknown.
715774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  StopTracking,
725774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
735774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// All typestate tracking of the object ceases.  Unlike StopTracking,
74c79ce4214cf4f81ae31146731ceb5d01cfcceb96Ted Kremenek  /// this is also enforced when the method body is inlined.
755774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  ///
765774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// In some cases, we obtain a better summary for this checker
775774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// by looking at the call site than by inlining the function.
785774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// Signifies that we should stop tracking the symbol even if
795774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// the function is inlined.
805774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  StopTrackingHard,
815774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
825774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// Performs the combined functionality of DecRef and StopTrackingHard.
835774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  ///
845774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// The models the effect that the called function decrements the reference
855774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// count of the argument and all typestate tracking on that argument
865774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// should cease.
875774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  DecRefAndStopTrackingHard,
885774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
895774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// Performs the combined functionality of DecRefMsg and StopTrackingHard.
905774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  ///
915774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// The models the effect that the called function decrements the reference
925774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// count of the argument and all typestate tracking on that argument
935774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// should cease.
945774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  DecRefMsgAndStopTrackingHard
955774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek};
965774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
975774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek/// RetEffect summarizes a call's retain/release behavior with respect
985774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek/// to its return value.
995774e390199a572d10b22c78a80ed2cdde94304dTed Kremenekclass RetEffect {
1005774e390199a572d10b22c78a80ed2cdde94304dTed Kremenekpublic:
1015774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  enum Kind {
1025774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// Indicates that no retain count information is tracked for
1035774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// the return value.
1045774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    NoRet,
1055774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// Indicates that the returned value is an owned (+1) symbol.
1065774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    OwnedSymbol,
1075774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// Indicates that the returned value is an owned (+1) symbol and
1085774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// that it should be treated as freshly allocated.
1095774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    OwnedAllocatedSymbol,
1105774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// Indicates that the returned value is an object with retain count
1115774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// semantics but that it is not owned (+0).  This is the default
1125774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// for getters, etc.
1135774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    NotOwnedSymbol,
1145774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// Indicates that the object is not owned and controlled by the
1155774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// Garbage collector.
1165774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    GCNotOwnedSymbol,
1175774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// Indicates that the return value is an owned object when the
1185774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// receiver is also a tracked object.
1195774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    OwnedWhenTrackedReceiver,
1205774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    // Treat this function as returning a non-tracked symbol even if
1215774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    // the function has been inlined. This is used where the call
1225774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    // site summary is more presise than the summary indirectly produced
1235774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    // by inlining the function
1245774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    NoRetHard
1255774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  };
1265774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
1275774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  /// Determines the object kind of a tracked object.
1285774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  enum ObjKind {
1295774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// Indicates that the tracked object is a CF object.  This is
1305774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// important between GC and non-GC code.
1315774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    CF,
1325774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// Indicates that the tracked object is an Objective-C object.
1335774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    ObjC,
1345774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    /// Indicates that the tracked object could be a CF or Objective-C object.
1355774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    AnyObj
1365774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  };
1375774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
1385774e390199a572d10b22c78a80ed2cdde94304dTed Kremenekprivate:
1395774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  Kind K;
1405774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  ObjKind O;
1415774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
1425774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {}
1435774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
1445774e390199a572d10b22c78a80ed2cdde94304dTed Kremenekpublic:
1455774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  Kind getKind() const { return K; }
1465774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
1475774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  ObjKind getObjKind() const { return O; }
1485774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
1495774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  bool isOwned() const {
1505774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    return K == OwnedSymbol || K == OwnedAllocatedSymbol ||
1515774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    K == OwnedWhenTrackedReceiver;
1525774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  }
1535774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
1545f7ac67c84e7b9a04fa4c5065e384f928c8f812fFariborz Jahanian  bool notOwned() const {
155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return K == NotOwnedSymbol;
1565f7ac67c84e7b9a04fa4c5065e384f928c8f812fFariborz Jahanian  }
1575f7ac67c84e7b9a04fa4c5065e384f928c8f812fFariborz Jahanian
1585774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  bool operator==(const RetEffect &Other) const {
1595774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    return K == Other.K && O == Other.O;
1605774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  }
1615774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
1625774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  static RetEffect MakeOwnedWhenTrackedReceiver() {
1635774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    return RetEffect(OwnedWhenTrackedReceiver, ObjC);
1645774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  }
1655774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
1665774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  static RetEffect MakeOwned(ObjKind o, bool isAllocated = false) {
1675774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, o);
1685774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  }
1695774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  static RetEffect MakeNotOwned(ObjKind o) {
1705774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    return RetEffect(NotOwnedSymbol, o);
1715774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  }
1725774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  static RetEffect MakeGCNotOwned() {
1735774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    return RetEffect(GCNotOwnedSymbol, ObjC);
1745774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  }
1755774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  static RetEffect MakeNoRet() {
1765774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    return RetEffect(NoRet);
1775774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  }
1785774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  static RetEffect MakeNoRetHard() {
1795774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek    return RetEffect(NoRetHard);
1805774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek  }
1815774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek};
18253c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek
18353c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek/// Encapsulates the retain count semantics on the arguments, return value,
18453c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek/// and receiver (if any) of a function/method call.
18553c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek///
18653c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek/// Note that construction of these objects is not highly efficient.  That
18753c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek/// is okay for clients where creating these objects isn't really a bottleneck.
18853c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek/// The purpose of the API is to provide something simple.  The actual
18953c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek/// static analyzer checker that implements retain/release typestate
19053c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek/// tracking uses something more efficient.
19153c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenekclass CallEffects {
19253c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek  llvm::SmallVector<ArgEffect, 10> Args;
19353c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek  RetEffect Ret;
19453c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek  ArgEffect Receiver;
19553c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek
19653c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek  CallEffects(const RetEffect &R) : Ret(R) {}
19753c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek
19853c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenekpublic:
19953c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek  /// Returns the argument effects for a call.
200ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  ArrayRef<ArgEffect> getArgs() const { return Args; }
20153c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek
20253c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek  /// Returns the effects on the receiver.
20353c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek  ArgEffect getReceiver() const { return Receiver; }
20453c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek
20553c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek  /// Returns the effect on the return value.
20653c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek  RetEffect getReturnValue() const { return Ret; }
20753c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek
20853c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek  /// Return the CallEfect for a given Objective-C method.
20953c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek  static CallEffects getEffect(const ObjCMethodDecl *MD);
21053c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek
21153c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek  /// Return the CallEfect for a given C/C++ function.
21253c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek  static CallEffects getEffect(const FunctionDecl *FD);
21353c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek};
21453c7ea1517fc9080b30b054c578cb407de12d5b5Ted Kremenek
2155774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek}}}
2165774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
2175774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek#endif
2185774e390199a572d10b22c78a80ed2cdde94304dTed Kremenek
219