Index: cfe/trunk/www/analyzer/annotations.html =================================================================== --- cfe/trunk/www/analyzer/annotations.html +++ cfe/trunk/www/analyzer/annotations.html @@ -60,6 +60,16 @@
Libkern +requires developers to inherit all heap allocated objects from OSObject +and to perform manual reference counting. +The reference counting model is very similar to MRR (manual retain-release) mode in +Objective-C +or to CoreFoundation reference counting. +Freshly-allocated objects start with a reference count of 1, +and calls to retain increment it, +while calls to release decrement it. +The object is deallocated whenever its reference count reaches zero.
+ +Manually incrementing and decrementing reference counts is error-prone: +over-retains lead to leaks, and over-releases lead to uses-after-free. +The analyzer can help the programmer to check for unbalanced +retain/release calls.
+ +The reference count checking is based on the principle of +locality: it should be possible to establish correctness +(lack of leaks/uses after free) by looking at each function body, +and the declarations (not the definitions) of all the functions it interacts +with.
+ +In order to support such reasoning, it should be possible to summarize +the behavior of each function, with respect to reference count +of its returned values and attributes.
+ +By default, the following summaries are assumed:
+These summaries can be overriden with the following +attributes:
+ +The os_returns_retained attribute (accessed through the macro +LIBKERN_RETURNS_RETAINED) plays a role identical to ns_returns_retained for functions +returning OSObject subclasses. +The attribute indicates that it is a callers responsibility to release the +returned object. +
+ + +The os_returns_not_retained attribute (accessed through the macro +LIBKERN_RETURNS_NOT_RETAINED) plays a role identical to ns_returns_not_retained for functions +returning OSObject subclasses. +The attribute indicates that the caller should not change the retain +count of the returned object. +
+ ++class MyClass { + OSObject *f; + LIBKERN_RETURNS_NOT_RETAINED OSObject *myFieldGetter(); +} + + +// Note that the annotation only has to be applied to the function declaration. +OSObject * MyClass::myFieldGetter() { + return f; +} ++ +
Similarly to ns_consumed attribute, +os_consumed (accessed through LIBKERN_CONSUMED) attribute, +applied to a parameter, +indicates that the call to the function consumes the parameter: +the callee should either release it or store it and release it in the destructor, +while the caller should assume one is subtracted from the reference count +after the call.
+ ++IOReturn addToList(LIBKERN_CONSUMED IOPMinformee *newInformee); ++ +
Similarly to ns_consumes_self, +the os_consumes_self attribute indicates that the method call +consumes the implicit this argument: the caller +should assume one was subtracted from the reference count of the object +after the call, and the callee has on obligation to either +release the argument, or store it and eventually release it in the +destructor.
+ ++void addThisToList(OSArray *givenList) LIBKERN_CONSUMES_THIS; ++ +
1. Non-retained out parameters, identified using + LIBKERN_RETURNS_NOT_RETAINED applied to parameters, e.g.:
+ ++void getterViaOutParam(LIBKERN_RETURNS_NOT_RETAINED OSObject **obj) ++ +
Such functions write a non-retained object into an out parameter, and the +caller has no further obligations.
+ +2. Retained out parameters, +identified using LIBKERN_RETURNS_RETAINED:
++void getterViaOutParam(LIBKERN_RETURNS_NOT_RETAINED OSObject **obj) ++
+In such cases a retained object is written into an out parameter, which the caller has then to release in order to avoid a leak. +
+ +These two cases are simple - but in practice a functions returning an out-parameter usually also return a return code, and then an out parameter may or may not be written, which conditionally depends on the exit code, e.g.:
+ ++bool maybeCreateObject(LIBKERN_RETURNS_RETAINED OSObject **obj); ++ +
For such functions, the usual semantics is that an object is written into on "success", and not written into on "failure".
+ +
For LIBKERN_RETURNS_RETAINED we assume the following definition of +success:
+ +For functions returning OSReturn or IOReturn +(any typedef to kern_return_t) success is defined as having an output of zero (kIOReturnSuccess is zero). +For all others, success is non-zero (e.g. non-nullptr for pointers)
+ +3. Retained out parameters on zero return +The annotation LIBKERN_RETURNS_RETAINED_ON_ZERO states +that a retained object is written into if and only if the function returns a zero value:
+ ++bool OSUnserializeXML(void *data, LIBKERN_RETURNS_RETAINED_ON_ZERO OSString **errString); ++ +
Then the caller has to release an object if the function has returned zero.
+ +4. Retained out parameters on non-zero return +Similarly, LIBKERN_RETURNS_RETAINED_ON_NONZERO specifies that a +retained object is written into the parameter if and only if the function has +returned a non-zero value.
+ +Note that for non-retained out parameters conditionals do not matter, as the +caller has no obligations regardless of whether an object is written into or +not.