Fix and improve the ARC spec's wording about unmanaged objects.
llvm-svn: 337524
This commit is contained in:
parent
34f5867310
commit
07fa4a49c4
|
@ -974,28 +974,66 @@ It is undefined behavior to access an ownership-qualified object through an
|
||||||
lvalue of a differently-qualified type, except that any non-``__weak`` object
|
lvalue of a differently-qualified type, except that any non-``__weak`` object
|
||||||
may be read through an ``__unsafe_unretained`` lvalue.
|
may be read through an ``__unsafe_unretained`` lvalue.
|
||||||
|
|
||||||
It is undefined behavior if a managed operation is performed on a ``__strong``
|
It is undefined behavior if the storage of a ``__strong`` or ``__weak``
|
||||||
or ``__weak`` object without a guarantee that it contains a primitive zero
|
object is not properly initialized before the first managed operation
|
||||||
bit-pattern, or if the storage for such an object is freed or reused without the
|
is performed on the object, or if the storage of such an object is freed
|
||||||
object being first assigned a null pointer.
|
or reused before the object has been properly deinitialized. Storage for
|
||||||
|
a ``__strong`` or ``__weak`` object may be properly initialized by filling
|
||||||
|
it with the representation of a null pointer, e.g. by acquiring the memory
|
||||||
|
with ``calloc`` or using ``bzero`` to zero it out. A ``__strong`` or
|
||||||
|
``__weak`` object may be properly deinitialized by assigning a null pointer
|
||||||
|
into it. A ``__strong`` object may also be properly initialized
|
||||||
|
by copying into it (e.g. with ``memcpy``) the representation of a
|
||||||
|
different ``__strong`` object whose storage has been properly initialized;
|
||||||
|
doing this properly deinitializes the source object and causes its storage
|
||||||
|
to no longer be properly initialized. A ``__weak`` object may not be
|
||||||
|
representation-copied in this way.
|
||||||
|
|
||||||
|
These requirements are followed automatically for objects whose
|
||||||
|
initialization and deinitialization are under the control of ARC:
|
||||||
|
|
||||||
|
* objects of static, automatic, and temporary storage duration
|
||||||
|
* instance variables of Objective-C objects
|
||||||
|
* elements of arrays where the array object's initialization and
|
||||||
|
deinitialization are under the control of ARC
|
||||||
|
* fields of Objective-C struct types where the struct object's
|
||||||
|
initialization and deinitialization are under the control of ARC
|
||||||
|
* non-static data members of Objective-C++ non-union class types
|
||||||
|
* Objective-C++ objects and arrays of dynamic storage duration created
|
||||||
|
with the ``new`` or ``new[]`` operators and destroyed with the
|
||||||
|
corresponding ``delete`` or ``delete[]`` operator
|
||||||
|
|
||||||
|
They are not followed automatically for these objects:
|
||||||
|
|
||||||
|
* objects of dynamic storage duration created in other memory, such as
|
||||||
|
that returned by ``malloc``
|
||||||
|
* union members
|
||||||
|
|
||||||
.. admonition:: Rationale
|
.. admonition:: Rationale
|
||||||
|
|
||||||
ARC cannot differentiate between an assignment operator which is intended to
|
ARC must perform special operations when initializing an object and
|
||||||
"initialize" dynamic memory and one which is intended to potentially replace
|
when destroying it. In many common situations, ARC knows when an
|
||||||
a value. Therefore the object's pointer must be valid before letting ARC at
|
object is created and when it is destroyed and can ensure that these
|
||||||
it. Similarly, C and Objective-C do not provide any language hooks for
|
operations are performed correctly. Otherwise, however, ARC requires
|
||||||
destroying objects held in dynamic memory, so it is the programmer's
|
programmer cooperation to establish its initialization invariants
|
||||||
responsibility to avoid leaks (``__strong`` objects) and consistency errors
|
because it is infeasible for ARC to dynamically infer whether they
|
||||||
(``__weak`` objects).
|
are intact. For example, there is no syntactic difference in C between
|
||||||
|
an assignment that is intended by the programmer to initialize a variable
|
||||||
|
and one that is intended to replace the existing value stored there,
|
||||||
|
but ARC must perform one operation or the other. ARC chooses to always
|
||||||
|
assume that objects are initialized (except when it is in charge of
|
||||||
|
initializing them) because the only workable alternative would be to
|
||||||
|
ban all code patterns that could potentially be used to access
|
||||||
|
uninitialized memory, and that would be too limiting. In practice,
|
||||||
|
this is rarely a problem because programmers do not generally need to
|
||||||
|
work with objects for which the requirements are not handled
|
||||||
|
automatically.
|
||||||
|
|
||||||
These requirements are followed automatically in Objective-C++ when creating
|
Note that dynamically-allocated Objective-C++ arrays of
|
||||||
objects of retainable object owner type with ``new`` or ``new[]`` and destroying
|
nontrivially-ownership-qualified type are not ABI-compatible with non-ARC
|
||||||
them with ``delete``, ``delete[]``, or a pseudo-destructor expression. Note
|
code because the non-ARC code will consider the element type to be POD.
|
||||||
that arrays of nontrivially-ownership-qualified type are not ABI compatible with
|
Such arrays that are ``new[]``'d in ARC translation units cannot be
|
||||||
non-ARC code because the element type is non-POD: such arrays that are
|
``delete[]``'d in non-ARC translation units and vice-versa.
|
||||||
``new[]``'d in ARC translation units cannot be ``delete[]``'d in non-ARC
|
|
||||||
translation units and vice-versa.
|
|
||||||
|
|
||||||
.. _arc.ownership.restrictions.pass_by_writeback:
|
.. _arc.ownership.restrictions.pass_by_writeback:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue