From 9da31cb1c51b9af40c832be3d670a299ceab6a74 Mon Sep 17 00:00:00 2001 From: John McCall Date: Tue, 27 Mar 2012 07:42:12 +0000 Subject: [PATCH] Update the ARC specification for several changes made in the last N months. This required a brief soliloquy about change in an uncertainly-versioned world. I believe I've gotten the right target versions on all these changes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153501 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/AutomaticReferenceCounting.html | 324 +++++++++++++++++++++++---- 1 file changed, 285 insertions(+), 39 deletions(-) diff --git a/docs/AutomaticReferenceCounting.html b/docs/AutomaticReferenceCounting.html index 74506b04b1..ff65f3be48 100644 --- a/docs/AutomaticReferenceCounting.html +++ b/docs/AutomaticReferenceCounting.html @@ -20,6 +20,16 @@ div.rationale em { font-style: normal } +/* Revisions are also italicized. */ +span.revision { + font-style: italic +} + +span.whenRevised { + font-weight: bold; + font-style: normal +} + div h1 { font-size: 2em; margin: .67em 0 } div div h1 { font-size: 1.5em; margin: .75em 0 } div div div h1 { font-size: 1.17em; margin: .83em 0 } @@ -209,6 +219,38 @@ adjusting the reference count, not by calling Block_copy.

+
+

Evolution

+ +

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.

+ +
+
@@ -216,8 +258,10 @@ adjusting the reference count, not by calling Block_copy.

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.

see the language extensions document.

-
+

Retainable object pointers

@@ -446,9 +490,9 @@ The rule about function calls is really just an application of the existing C/C++ rule about calling functions through an incompatible function type, but it's useful to state it explicitly.

- + -
+

Retained return values

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.

+

Unretained return values

@@ -530,7 +574,8 @@ that it returns a pointer which is guaranteed to be valid at least as long as the innermost autorelease pool. There are no additional semantics enforced in the definition of such a method; it merely enables optimizations in callers.

-
+ +

Bridged casts

@@ -569,9 +614,9 @@ object pointers.

cast purely to convince ARC to emit an unbalanced retain or release, respectively, is poor form.

-
+ - +

Restrictions

@@ -593,28 +638,125 @@ management of the lifetime of objects if they may be freely passed around as unmanaged types. The bridged casts are provided so that the programmer may explicitly describe whether the cast transfers control into or out of ARC.

- -

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.

+ + + +
+

Conversion to retainable object pointer type of + expressions with known semantics

+ +

[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.

+ + + +
+

Conversion from retainable object pointer type in certain contexts

+ +

[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.

+ +
+ + + +

Ownership qualification

@@ -723,6 +865,29 @@ already exists, then its ownership qualification must equal the ownership of the property; otherwise, the instance variable is created with that ownership qualification.

+

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.

+
@@ -762,11 +927,11 @@ finally, the old pointee is released. This is not performed atomically; external synchronization must be used to make this safe in the face of concurrent loads and stores.
  • For __weak objects, the lvalue is updated to point to the -new pointee, unless that object is currently undergoing deallocation, -in which case it the lvalue is updated to a null pointer. This must -execute atomically with respect to other assignments to the object, to -reads from the object, and to the final release of the new pointed-to -value.
  • +new pointee, unless the new pointee is an object currently undergoing +deallocation, in which case the lvalue is updated to a null pointer. +This must execute atomically with respect to other assignments to the +object, to reads from the object, and to the final release of the new +pointee.
  • For __unsafe_unretained objects, the new pointee is stored into the lvalue using primitive semantics.
  • For __autoreleasing objects, the new pointee is retained, @@ -969,7 +1134,7 @@ not immediately seen in the original argument variable.

    the argument, and no further work is required for the pass-by-writeback.
  • Otherwise, a temporary of type T __autoreleasing is created and initialized to a null pointer.
  • -
  • If the argument is not an Objective-C method parameter marked +
  • If the parameter is not an Objective-C method parameter marked out, then *p is read, and the result is written into the temporary with primitive semantics.
  • The address of the temporary is passed as the argument to the @@ -1007,17 +1172,17 @@ object.

    nontrivally ownership-qualified types are considered non-POD: in C++11 terms, they are not trivially default constructible, copy constructible, move constructible, copy assignable, move assignable, -or destructible. It is a violation of C++ One Definition Rule to use -a class outside of ARC that, under ARC, would have an +or destructible. It is a violation of C++'s One Definition Rule to use +a class outside of ARC that, under ARC, would have a nontrivially ownership-qualified member.

    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.

    @@ -1186,7 +1351,7 @@ mechanical system, they are only imperfectly kept, especially as they haven't always even been precisely defined. While it is possible to define low-level ownership semantics with attributes like ns_returns_retained, this attribute allows the user to -communicate semantic intent, which of use both to ARC (which, e.g., +communicate semantic intent, which is of use both to ARC (which, e.g., treats calls to init specially) and the static analyzer.

    @@ -1278,7 +1443,7 @@ of ARC.

    more prone than most code to signature errors, i.e. errors where a call was emitted against one method signature, but the implementing method has an incompatible signature. Having more precise type -information helps drastically lower this risks, as well as catching +information helps drastically lower this risk, as well as catching a number of latent bugs.

    @@ -1345,7 +1510,7 @@ clearer.

    - +

    Miscellaneous

    @@ -1517,7 +1682,7 @@ the variable with __strong, which will make the variable mutable again and cause the loop to retain the objects it encounters.

    - +

    Blocks

    @@ -1644,6 +1809,87 @@ user with good cheer.

    +
    +

    C retainable pointer types

    + +

    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.

    + +
    +

    Auditing of C retainable pointer interfaces

    + +

    [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 parameter of C retainable pointer type is assumed to not be +consumed unless it is marked with the cf_consumed attribute, and
    • +
    • A result of C retainable pointer type is assumed to not be +returned retained unless the function is either +marked cf_returns_retained or it follows +the create/copy naming convention and is not +marked cf_returns_not_retained.
    • +
    + +

    A function obeys the create/copy naming +convention if its name contains as a substring:

    +
      +
    • either Create or Copy not followed by a lowercase letter, or
    • +
    • either create or copy not 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.

    + +
    + +
    +
    -- 2.50.1