HP aC++/HP C Programmer's Guide (B3901-90036; A.06.26; September 2011)

1. The return value of a call to such a function points to a memory location or can be
a null pointer.
2. On return of such a call (before the return value is assigned to another variable in
the caller), the memory location mentioned in 1. can be referenced only through
the function return value; e.g., if the pointer value is saved into another global
variable in the call, the function is not qualified for the malloc attribute.
3. The lifetime of the memory location returned by such a function is defined as the
period of program execution between a) the point at which the call returns and b)
the point at which the memory pointer is passed to the corresponding deallocation
function. Within the lifetime of the memory object, no other calls to malloc routines
should return the address of the same object or any address pointing into that object.
Many wrappers around malloc() obey these rules. (The compiler already knows that
malloc() itself obeys these rules.)
Example:
void *foo(int i) __attribute__ ((malloc));
attribute non_exposing
__attribute__ ((non_exposing))
The non_exposing attribute is used to improve optimization by telling the compiler
that this function does not cause any address it can _derive_ from any of its formal
parameters to become visible after a call to the function returns.
An address becomes visible if the function returns a value from which it can be
_directly derived_ or if the function stores it in a memory location that is visible
(can be referenced directly or indirectly) after the call to the function returns.(Note that
there is no such thing as a formal parameter of array type. A formal parameter declared
to be of type "array of T" is treated as being of type "pointer to T"; and when an actual
argument is of type "array of T", a pointer to the first element of that array is passed.)Many
wrappers around free() obey these rules. (The compiler already knows that free() itself
obeys these rules.) Many functions that have nothing to do with memory allocation also
obey these rules.For the purposes of the specification above, the definitions of the terms
_directly derived_ and _derived_ are as follows:The addresses that can be
_directly derived_ from some value V are the following:
* If V is or can be converted to a pointer value (except by a C++ user-defined conversion),
then consider P to be a pointer object containing that value. The value of any expression
_based on_ P (as defined in C99) can be _directly derived_ from V. For
example, if P is a pointer object containing the value V, then "P", "&P->f", "&P[i]",
and "P+j" are expressions based on P, and thus their values are _directly derived_
from V.* If V is an array, then any addresses that can be _directly derived_ from
V’s elements can be _directly derived_ from V.* If V is a class, struct, or union,
then any addresses that can be _directly derived_ from V’s nonstatic data members
can be _directly derived_ from V.* If V is a reference, then &V can be _directly
Attributes 143