mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-30 17:21:10 +00:00
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
|
||||
may be read through an ``__unsafe_unretained`` lvalue.
|
||||
|
||||
It is undefined behavior if a managed operation is performed on a ``__strong``
|
||||
or ``__weak`` object without a guarantee that it contains a primitive zero
|
||||
bit-pattern, or if the storage for such an object is freed or reused without the
|
||||
object being first assigned a null pointer.
|
||||
It is undefined behavior if the storage of a ``__strong`` or ``__weak``
|
||||
object is not properly initialized before the first managed operation
|
||||
is performed on the object, or if the storage of such an object is freed
|
||||
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
|
||||
|
||||
ARC cannot differentiate between an assignment operator which is intended to
|
||||
"initialize" dynamic memory and one which is intended to potentially replace
|
||||
a value. Therefore the object's pointer must be valid before letting ARC at
|
||||
it. Similarly, C and Objective-C do not provide any language hooks for
|
||||
destroying objects held in dynamic memory, so it is the programmer's
|
||||
responsibility to avoid leaks (``__strong`` objects) and consistency errors
|
||||
(``__weak`` objects).
|
||||
ARC must perform special operations when initializing an object and
|
||||
when destroying it. In many common situations, ARC knows when an
|
||||
object is created and when it is destroyed and can ensure that these
|
||||
operations are performed correctly. Otherwise, however, ARC requires
|
||||
programmer cooperation to establish its initialization invariants
|
||||
because it is infeasible for ARC to dynamically infer whether they
|
||||
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
|
||||
objects of retainable object owner type with ``new`` or ``new[]`` and destroying
|
||||
them with ``delete``, ``delete[]``, or a pseudo-destructor expression. Note
|
||||
that arrays of nontrivially-ownership-qualified type are not ABI compatible with
|
||||
non-ARC code because the element type is non-POD: such arrays that are
|
||||
``new[]``'d in ARC translation units cannot be ``delete[]``'d in non-ARC
|
||||
translation units and vice-versa.
|
||||
Note that dynamically-allocated Objective-C++ arrays of
|
||||
nontrivially-ownership-qualified type are not ABI-compatible with non-ARC
|
||||
code because the non-ARC code will consider the element type to be POD.
|
||||
Such arrays that are ``new[]``'d in ARC translation units cannot be
|
||||
``delete[]``'d in non-ARC translation units and vice-versa.
|
||||
|
||||
.. _arc.ownership.restrictions.pass_by_writeback:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user