User's Guide

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 derived_ from V.The addresses that can be _derived_ from some value V
are the addresses that can be _directly derived_ from V and the addresses that can be
_derived_ from the result of dereferencing those addresses. The function does not store addresses
passed to it as arguments to any memory location that is visible (can be referenced directly or
indirectly) after the call to this function returns.
Example:
void foo(int *pi) __attribute__ ((non_exposing));
attribute noreturn
__attribute__ ((noreturn))
Attributes 117