Skip to content

Commit 9cc574d

Browse files
committed
Clarify the semantics of init methods, and point out a few places
where mismatched semantics can cause undefined behavior. llvm-svn: 133341
1 parent f8d4799 commit 9cc574d

File tree

1 file changed

+67
-38
lines changed

1 file changed

+67
-38
lines changed

clang/docs/AutomaticReferenceCounting.html

Lines changed: 67 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -424,20 +424,29 @@ <h1>Consumed parameters</h1>
424424

425425
<p>The implicit <tt>self</tt> parameter of a method may be marked as
426426
consumed by adding <tt>__attribute__((ns_consumes_self))</tt> to the
427-
method declaration. Methods in
428-
the <tt>init</tt> <a href="#family">family</a> are implicitly
429-
marked <tt>__attribute__((ns_consumes_self))</tt>.</p>
430-
431-
<p>It is undefined behavior if an Objective-C message send of a method
432-
with <tt>ns_consumed</tt> parameters (other than self) is made to a
433-
null pointer.</p>
434-
435-
<div class="rationale"><p>Rationale: in fact, it's probably a
436-
guaranteed leak.</p></div>
427+
method declaration. Methods in the <tt>init</tt>
428+
<a href="#family">family</a> are treated as if they were implicitly
429+
marked with this attribute.</p>
430+
431+
<p>It is undefined behavior if an Objective-C message send to a method
432+
with <tt>ns_consumed</tt> parameters (other than self) is made with a
433+
null receiver. It is undefined behavior if the method to which an
434+
Objective-C message send statically resolves to has a different set
435+
of <tt>ns_consumed</tt> parameters than the method it dynamically
436+
resolves to. It is undefined behavior if a block or function call is
437+
made through a static type with a different set of <tt>ns_consumed</tt>
438+
parameters than the implementation of the called block or function.</p>
439+
440+
<div class="rationale"><p>Rationale: consumed parameters with null
441+
receiver are a guaranteed leak. Mismatches with consumed parameters
442+
will cause over-retains or over-releases, depending on the direction.
443+
The rule about function calls is really just an application of the
444+
existing C/C++ rule about calling functions through an incompatible
445+
function type, but it's useful to state it explicitly.</p></div>
437446

438447
</div>
439448

440-
<div id="objects.operands.retained-returns">
449+
<div id="objects.operands.retained_returns">
441450
<h1>Retained return values</h1>
442451

443452
<p>A function or method which returns a retainable object pointer type
@@ -474,6 +483,20 @@ <h1>Retained return values</h1>
474483
method <tt>__attribute__((ns_returns_not_retained))</tt>.</p>
475484
</div>
476485

486+
<p>It is undefined behavior if the method to which an Objective-C
487+
message send statically resolves has different retain semantics on its
488+
result from the method it dynamically resolves to. It is undefined
489+
behavior if a block or function call is made through a static type
490+
with different retain semantics on its result from the implementation
491+
of the called block or function.</p>
492+
493+
<div class="rationale"><p>Rationale: Mismatches with returned results
494+
will cause over-retains or over-releases, depending on the direction.
495+
Again, the rule about function calls is really just an application of
496+
the existing C/C++ rule about calling functions through an
497+
incompatible function type.</p></div>
498+
499+
477500
<div id="objects.operands.other-returns">
478501
<h1>Unretained return values</h1>
479502

@@ -1038,9 +1061,9 @@ <h1>Method families</h1>
10381061
Objective-C pointer type. Additionally, a program is ill-formed if it
10391062
declares or contains a call to an <tt>init</tt> method whose return
10401063
type is neither <tt>id</tt> nor a pointer to a super-class or
1041-
sub-class of either the declaring class, if the method was declared on
1042-
a class, or the static receiver type of the call, if it was declared
1043-
on a protocol.</p>
1064+
sub-class of the declaring class (if the method was declared on
1065+
a class) or the static receiver type of the call (if it was declared
1066+
on a protocol).</p>
10441067

10451068
<div class="rationale"><p>Rationale: there are a fair number of existing
10461069
methods with <tt>init</tt>-like selectors which nonetheless don't
@@ -1051,10 +1074,14 @@ <h1>Method families</h1>
10511074
methods as <tt>init</tt> methods if they aren't meant to be. It was
10521075
felt that implicitly defining these methods out of the family based on
10531076
the exact relationship between the return type and the declaring class
1054-
would much too subtle and fragile. Therefore we identify a small
1077+
would be much too subtle and fragile. Therefore we identify a small
10551078
number of legitimate-seeming return types and call everything else an
10561079
error. This serves the secondary purpose of encouraging programmers
1057-
not to accidentally give methods names in the <tt>init</tt> family.</p></div>
1080+
not to accidentally give methods names in the <tt>init</tt> family.</p>
1081+
1082+
<p>Note that a method with an <tt>init</tt>-family selector which
1083+
returns a non-Objective-C type (e.g. <tt>void</tt>) is perfectly
1084+
well-formed; it simply isn't in the <tt>init</tt> family.</p></div>
10581085
</li>
10591086
</ul>
10601087

@@ -1105,40 +1132,42 @@ <h1>Semantics of method families</h1>
11051132

11061133
<p>Methods in the <tt>alloc</tt>, <tt>copy</tt>, <tt>mutableCopy</tt>,
11071134
and <tt>new</tt> families &mdash; that is, methods in all the
1108-
currently-defined families except <tt>init</tt> &mdash; transfer
1109-
ownership of a +1 retain count on their return value to the calling
1110-
function, as if they were implicitly annotated with
1111-
the <tt>ns_returns_retained</tt> attribute. However, this is not true
1112-
if the method has either of the <tt>ns_returns_autoreleased</tt> or
1135+
currently-defined families except <tt>init</tt> &mdash; implicitly
1136+
<a href="#objects.operands.retained_returns">return a retained
1137+
object</a> as if they were annotated with
1138+
the <tt>ns_returns_retained</tt> attribute. This can be overridden by
1139+
annotating the method with either of
1140+
the <tt>ns_returns_autoreleased</tt> or
11131141
<tt>ns_returns_not_retained</tt> attributes.</p>
11141142

11151143
<div id="family.semantics.init">
11161144
<h1>Semantics of <tt>init</tt></h1>
11171145

1118-
<p>Methods in the <tt>init</tt> family must be transferred ownership
1119-
of a +1 retain count on their <tt>self</tt> parameter, exactly as if
1120-
the method had the <tt>ns_consumes_self</tt> attribute, and must
1121-
transfer ownership of a +1 retain count on their return value, exactly
1122-
as if they method had the <tt>ns_returns_retained</tt> attribute.
1123-
Neither of these may be altered through attributes.</p>
1146+
<p>Methods in the <tt>init</tt> family implicitly
1147+
<a href="#objects.operands.consumed">consume</a> their <tt>self</tt>
1148+
parameter and <a href="#objects.operands.retained_returns">return a
1149+
retained object</a>. Neither of these properties can be altered
1150+
through attributes.</p>
11241151

11251152
<p>A call to an <tt>init</tt> method with a receiver that is either
11261153
<tt>self</tt> (possibly parenthesized or casted) or <tt>super</tt> is
11271154
called a <span class="term">delegate init call</span>. It is an error
11281155
for a delegate init call to be made except from an <tt>init</tt>
11291156
method, and excluding blocks within such methods.</p>
11301157

1131-
<p>The variable <tt>self</tt> is mutable in an <tt>init</tt> method
1132-
and is implicitly qualified as <tt>__strong</tt>. However, a program
1133-
is ill-formed, no diagnostic required, if it alters <tt>self</tt>
1134-
except to assign it the immediate result of a delegate init call. It
1135-
is an error to use the previous value of <tt>self</tt> after the
1136-
completion of a delegate init call.</p>
1137-
1138-
<p>A program is ill-formed, no diagnostic required, if it causes two
1139-
or more calls to <tt>init</tt> methods on the same object, except that
1140-
each <tt>init</tt> method invocation may perform at most one
1141-
delegate init call.</p>
1158+
<p>As an exception to the <a href="misc.self">usual rule</a>, the
1159+
variable <tt>self</tt> is mutable in an <tt>init</tt> method and has
1160+
the usual semantics for a <tt>__strong</tt> variable. However, it is
1161+
undefined behavior and the program is ill-formed, no diagnostic
1162+
required, if an <tt>init</tt> method attempts to use the previous
1163+
value of <tt>self</tt> after the completion of a delegate init call.
1164+
It is conventional, but not required, for an <tt>init</tt> method to
1165+
return <tt>self</tt>.</p>
1166+
1167+
<p>It is undefined behavior for a program to cause two or more calls
1168+
to <tt>init</tt> methods on the same object, except that
1169+
each <tt>init</tt> method invocation may perform at most one delegate
1170+
init call.</p>
11421171

11431172
</div> <!-- family.semantics.init -->
11441173

0 commit comments

Comments
 (0)