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