From: John McCall Date: Sat, 18 Jun 2011 08:15:19 +0000 (+0000) Subject: Clarify the semantics of init methods, and point out a few places X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=be16b8986ed8203aaa8035b3ce1b217729c0238f;p=clang Clarify the semantics of init methods, and point out a few places where mismatched semantics can cause undefined behavior. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133341 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/AutomaticReferenceCounting.html b/docs/AutomaticReferenceCounting.html index 1150614254..7ee3a154f3 100644 --- a/docs/AutomaticReferenceCounting.html +++ b/docs/AutomaticReferenceCounting.html @@ -424,20 +424,29 @@ rolled into the initialization of the parameter.

The implicit self parameter of a method may be marked as consumed by adding __attribute__((ns_consumes_self)) to the -method declaration. Methods in -the init family are implicitly -marked __attribute__((ns_consumes_self)).

- -

It is undefined behavior if an Objective-C message send of a method -with ns_consumed parameters (other than self) is made to a -null pointer.

- -

Rationale: in fact, it's probably a -guaranteed leak.

+method declaration. Methods in the init +family are treated as if they were implicitly +marked with this attribute.

+ +

It is undefined behavior if an Objective-C message send to a method +with ns_consumed parameters (other than self) is made with a +null receiver. It is undefined behavior if the method to which an +Objective-C message send statically resolves to has a different set +of ns_consumed parameters than the method it dynamically +resolves to. It is undefined behavior if a block or function call is +made through a static type with a different set of ns_consumed +parameters than the implementation of the called block or function.

+ +

Rationale: consumed parameters with null +receiver are a guaranteed leak. Mismatches with consumed parameters +will cause over-retains or over-releases, depending on the direction. +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 @@ -474,6 +483,20 @@ 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 +result from the method it dynamically resolves to. It is undefined +behavior if a block or function call is made through a static type +with different retain semantics on its result from the implementation +of the called block or function.

+ +

Rationale: Mismatches with returned results +will cause over-retains or over-releases, depending on the direction. +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

@@ -1038,9 +1061,9 @@ but performing:with would not.

Objective-C pointer type. Additionally, a program is ill-formed if it declares or contains a call to an init method whose return type is neither id nor a pointer to a super-class or -sub-class of either the declaring class, if the method was declared on -a class, or the static receiver type of the call, if it was declared -on a protocol.

+sub-class of the declaring class (if the method was declared on +a class) or the static receiver type of the call (if it was declared +on a protocol).

Rationale: there are a fair number of existing methods with init-like selectors which nonetheless don't @@ -1051,10 +1074,14 @@ of init methods, it's very important not to treat these methods as init methods if they aren't meant to be. It was felt that implicitly defining these methods out of the family based on the exact relationship between the return type and the declaring class -would much too subtle and fragile. Therefore we identify a small +would be much too subtle and fragile. Therefore we identify a small number of legitimate-seeming return types and call everything else an error. This serves the secondary purpose of encouraging programmers -not to accidentally give methods names in the init family.

+not to accidentally give methods names in the init family.

+ +

Note that a method with an init-family selector which +returns a non-Objective-C type (e.g. void) is perfectly +well-formed; it simply isn't in the init family.

@@ -1105,22 +1132,22 @@ semantics for its parameters and return type.

Methods in the alloc, copy, mutableCopy, and new families — that is, methods in all the -currently-defined families except init — transfer -ownership of a +1 retain count on their return value to the calling -function, as if they were implicitly annotated with -the ns_returns_retained attribute. However, this is not true -if the method has either of the ns_returns_autoreleased or +currently-defined families except init — implicitly +return a retained +object as if they were annotated with +the ns_returns_retained attribute. This can be overridden by +annotating the method with either of +the ns_returns_autoreleased or ns_returns_not_retained attributes.

Semantics of init

-

Methods in the init family must be transferred ownership -of a +1 retain count on their self parameter, exactly as if -the method had the ns_consumes_self attribute, and must -transfer ownership of a +1 retain count on their return value, exactly -as if they method had the ns_returns_retained attribute. -Neither of these may be altered through attributes.

+

Methods in the init family implicitly +consume their self +parameter and return a +retained object. Neither of these properties can be altered +through attributes.

A call to an init method with a receiver that is either self (possibly parenthesized or casted) or super is @@ -1128,17 +1155,19 @@ called a delegate init call. It is an error for a delegate init call to be made except from an init method, and excluding blocks within such methods.

-

The variable self is mutable in an init method -and is implicitly qualified as __strong. However, a program -is ill-formed, no diagnostic required, if it alters self -except to assign it the immediate result of a delegate init call. It -is an error to use the previous value of self after the -completion of a delegate init call.

- -

A program is ill-formed, no diagnostic required, if it causes two -or more calls to init methods on the same object, except that -each init method invocation may perform at most one -delegate init call.

+

As an exception to the usual rule, the +variable self is mutable in an init method and has +the usual semantics for a __strong variable. However, it is +undefined behavior and the program is ill-formed, no diagnostic +required, if an init method attempts to use the previous +value of self after the completion of a delegate init call. +It is conventional, but not required, for an init method to +return self.

+ +

It is undefined behavior for a program to cause two or more calls +to init methods on the same object, except that +each init method invocation may perform at most one delegate +init call.