Fix and improve the ARC spec's wording about unmanaged objects.

llvm-svn: 337524
This commit is contained in:
John McCall 2018-07-20 05:40:09 +00:00
parent 34f5867310
commit 07fa4a49c4
1 changed files with 56 additions and 18 deletions

View File

@ -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: