From 9da31cb1c51b9af40c832be3d670a299ceab6a74 Mon Sep 17 00:00:00 2001
From: John McCall
ARC is under continual evolution, and this document must be updated +as the language progresses.
+ +If a change increases the expressiveness of the language, for +example by lifting a restriction or by adding new syntax, the change +will be annotated with a revision marker, like so:
+ +
+ ARC applies to Objective-C pointer types, block pointer types, and
+ [beginning Apple
+ 8.0, LLVM 3.8] BPTRs declared within extern
+ "BCPL"
blocks.
+
+
+For now, it is sensible to version this document by the releases of
+its sole implementation (and its host project), clang.
+LLVM X.Y
refers to an open-source release of clang from the
+LLVM project. Apple X.Y
refers to an Apple-provided release of
+the Apple LLVM Compiler. Other organizations that prepare their own,
+separately-versioned clang releases and wish to maintain similar
+information in this document should send requests to cfe-dev.
If a change decreases the expressiveness of the language, for +example by imposing a new restriction, this should be taken as an +oversight in the original specification and something to be avoided +in all versions. Such changes are generally to be avoided.
+ +Automatic Reference Counting implements automatic memory management for Objective-C objects and blocks, freeing the programmer from the -need explicitly insert retains and releases. It does not provide a -cycle collector; users must explicitly manage lifetime instead.
+need to explicitly insert retains and releases. It does not provide a +cycle collector; users must explicitly manage the lifetime of their +objects, breaking cycles manually or with weak or unsafe +references.ARC may be explicitly enabled with the compiler
flag -fobjc-arc. It may also be explicitly disabled with the
@@ -229,7 +273,7 @@ appearing on the compile line wins
.
A function or method which returns a retainable object pointer type @@ -483,7 +527,6 @@ and new families are implicitly marked __attribute__((ns_returns_retained)). This may be suppressed by explicitly marking the method __attribute__((ns_returns_not_retained)).
-It is undefined behavior if the method to which an Objective-C message send statically resolves has different retain semantics on its @@ -498,6 +541,7 @@ Again, the rule about function calls is really just an application of the existing C/C++ rule about calling functions through an incompatible function type.
An unbridged cast to a retainable object pointer type of the return -value of a Objective-C message send which yields a non-retainable -pointer is treated as a __bridge_transfer cast -if:
+However, the following exceptions apply.
+ + + +[beginning Apple + 4.0, LLVM 3.1] These exceptions have been greatly expanded; + they previously applied only to a much-reduced subset which is + difficult to categorize but which included null pointers, message + sends (under the given rules), and the various global constants.
+ +An unbridged conversion to a retainable object pointer type from a +type other than a retainable object pointer type is ill-formed, as +discussed above, unless the operand of the cast has a syntactic form +which is known retained, known unretained, or known +retain-agnostic.
+ +An expression is known retain-agnostic if +it is:
+An expression is known unretained if it +is an rvalue of C retainable +pointer type and it is:
+An expression is known retained if it is +an rvalue of C retainable pointer type +and it is:
Otherwise the cast is treated as a __bridge cast.
+Furthermore:
+If the cast operand is known retained, the conversion is treated as +a __bridge_transfer cast. If the cast operand is known +unretained or known retain-agnostic, the conversion is treated as +a __bridge cast.
- +Rationale: Bridging casts are annoying. +Absent the ability to completely automate the management of CF +objects, however, we are left with relatively poor attempts to reduce +the need for a glut of explicit bridges. Hence these rules.
+ +We've so far consciously refrained from implicitly turning retained +CF results from function calls into __bridge_transfer casts. +The worry is that some code patterns — for example, creating a +CF value, assigning it to an ObjC-typed local, and then +calling CFRelease when done — are a bit too likely to +be accidentally accepted, leading to mysterious behavior.
[beginning Apple + 4.0, LLVM 3.1]
+ +If an expression of retainable object pointer type is explicitly +cast to a C retainable pointer type, +the program is ill-formed as discussed above unless the result is +immediately used:
+ +Rationale: Consumed parameters are left out +because ARC would naturally balance them with a retain, which was +judged too treacherous. This is in part because several of the most +common consuming functions are in the Release family, and it +would be quite unfortunate for explicit releases to be silently +balanced out in this way.
A property of retainable object pointer type which is synthesized +without a source of ownership has the ownership of its associated +instance variable, if it already exists; otherwise, +[beginning Apple 3.1, +LLVM 3.1] its ownership is implicitly strong. +Prior to this revision, it was ill-formed to synthesize such a +property.
+ +Rationale: using strong by default +is safe and consistent with the generic ARC rule about +inferring ownership. It +is, unfortunately, inconsistent with the non-ARC rule which states +that such properties are implicitly assign. However, that +rule is clearly untenable in ARC, since it leads to default-unsafe +code. The main merit to banning the properties is to avoid confusion +with non-ARC practice, which did not ultimately strike us as +sufficient to justify requiring extra syntax and (more importantly) +forcing novices to understand ownership rules just to declare a +property when the default is so reasonable. Changing the rule away +from non-ARC practice was acceptable because we had conservatively +banned the synthesis in order to give ourselves exactly this +leeway.
Rationale: unlike in C, we can express all the necessary ARC semantics for ownership-qualified subobjects as suboperations of the (default) special member functions for the class. These functions then become non-trivial. This has the non-obvious -repercussion that the class will have a non-trivial copy constructor -and non-trivial destructor; if it wouldn't outside of ARC, this means -that objects of the type will be passed and returned in an +result that the class will have a non-trivial copy constructor and +non-trivial destructor; if this would not normally be true outside of +ARC, objects of the type will be passed and returned in an ABI-incompatible manner.
A type is a C retainable pointer type +if it is a pointer to (possibly qualified) void or a +pointer to a (possibly qualifier) struct or class +type.
+ +Rationale: ARC does not manage pointers of +CoreFoundation type (or any of the related families of retainable C +pointers which interoperate with Objective-C for retain/release +operation). In fact, ARC does not even know how to distinguish these +types from arbitrary C pointer types. The intent of this concept is +to filter out some obviously non-object types while leaving a hook for +later tightening if a means of exhaustively marking CF types is made +available.
[beginning Apple 4.0, LLVM 3.1]
+ +A C function may be marked with the cf_audited_transfer +attribute to express that, except as otherwise marked with attributes, +it obeys the parameter (consuming vs. non-consuming) and return +(retained vs. non-retained) conventions for a C function of its name, +namely:
+ +A function obeys the create/copy naming +convention if its name contains as a substring:
+Createor
Copynot followed by a lowercase letter, or
createor
copynot followed by a lowercase +letter and not preceded by any letter, whether uppercase or lowercase.
A second attribute, cf_unknown_transfer, signifies that a +function's transfer semantics cannot be accurately captured using any +of these annotations. A program is ill-formed if it annotates the +same function with both cf_audited_transfer +and cf_unknown_transfer.
+ +A pragma is provided to faciliate the mass annotation of interfaces:
+ +#pragma arc_cf_code_audited begin +... +#pragma arc_cf_code_audited end+ +
All C functions declared within the extent of this pragma are +treated as if annotated with the cf_audited_transfer +attribute unless they otherwise have the cf_unknown_transfer +attribute. The pragma is accepted in all language modes. A program +is ill-formed if it attempts to change files, whether by including a +file or ending the current file, within the extent of this pragma.
+ +It is possible to test for all the features in this section with +__has_feature(arc_cf_code_audited).
+ +Rationale: A significant inconvenience in +ARC programming is the necessity of interacting with APIs based around +C retainable pointers. These features are designed to make it +relatively easy for API authors to quickly review and annotate their +interfaces, in turn improving the fidelity of tools such as the static +analyzer and ARC. The single-file restriction on the pragma is +designed to eliminate the risk of accidentally annotating some other +header's interfaces.