.. | |
------------------------------------------------------------------- | |
NOTE: This file is automatically generated by running clang-tblgen | |
-gen-attr-docs. Do not edit this file by hand!! | |
------------------------------------------------------------------- | |
=================== | |
Attributes in Clang | |
=================== | |
.. contents:: | |
:local: | |
Introduction | |
============ | |
This page lists the attributes currently supported by Clang. | |
Function Attributes | |
=================== | |
interrupt | |
--------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on | |
ARM targets. This attribute may be attached to a function definition and | |
instructs the backend to generate appropriate function entry/exit code so that | |
it can be used directly as an interrupt service routine. | |
The parameter passed to the interrupt attribute is optional, but if | |
provided it must be a string literal with one of the following values: "IRQ", | |
"FIQ", "SWI", "ABORT", "UNDEF". | |
The semantics are as follows: | |
- If the function is AAPCS, Clang instructs the backend to realign the stack to | |
8 bytes on entry. This is a general requirement of the AAPCS at public | |
interfaces, but may not hold when an exception is taken. Doing this allows | |
other AAPCS functions to be called. | |
- If the CPU is M-class this is all that needs to be done since the architecture | |
itself is designed in such a way that functions obeying the normal AAPCS ABI | |
constraints are valid exception handlers. | |
- If the CPU is not M-class, the prologue and epilogue are modified to save all | |
non-banked registers that are used, so that upon return the user-mode state | |
will not be corrupted. Note that to avoid unnecessary overhead, only | |
general-purpose (integer) registers are saved in this way. If VFP operations | |
are needed, that state must be saved manually. | |
Specifically, interrupt kinds other than "FIQ" will save all core registers | |
except "lr" and "sp". "FIQ" interrupts will save r0-r7. | |
- If the CPU is not M-class, the return instruction is changed to one of the | |
canonical sequences permitted by the architecture for exception return. Where | |
possible the function itself will make the necessary "lr" adjustments so that | |
the "preferred return address" is selected. | |
Unfortunately the compiler is unable to make this guarantee for an "UNDEF" | |
handler, where the offset from "lr" to the preferred return address depends on | |
the execution state of the code which generated the exception. In this case | |
a sequence equivalent to "movs pc, lr" will be used. | |
availability | |
------------ | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
The ``availability`` attribute can be placed on declarations to describe the | |
lifecycle of that declaration relative to operating system versions. Consider | |
the function declaration for a hypothetical function ``f``: | |
.. code-block:: c++ | |
void f(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.6,obsoleted=10.7))); | |
The availability attribute states that ``f`` was introduced in Mac OS X 10.4, | |
deprecated in Mac OS X 10.6, and obsoleted in Mac OS X 10.7. This information | |
is used by Clang to determine when it is safe to use ``f``: for example, if | |
Clang is instructed to compile code for Mac OS X 10.5, a call to ``f()`` | |
succeeds. If Clang is instructed to compile code for Mac OS X 10.6, the call | |
succeeds but Clang emits a warning specifying that the function is deprecated. | |
Finally, if Clang is instructed to compile code for Mac OS X 10.7, the call | |
fails because ``f()`` is no longer available. | |
The availability attribute is a comma-separated list starting with the | |
platform name and then including clauses specifying important milestones in the | |
declaration's lifetime (in any order) along with additional information. Those | |
clauses can be: | |
introduced=\ *version* | |
The first version in which this declaration was introduced. | |
deprecated=\ *version* | |
The first version in which this declaration was deprecated, meaning that | |
users should migrate away from this API. | |
obsoleted=\ *version* | |
The first version in which this declaration was obsoleted, meaning that it | |
was removed completely and can no longer be used. | |
unavailable | |
This declaration is never available on this platform. | |
message=\ *string-literal* | |
Additional message text that Clang will provide when emitting a warning or | |
error about use of a deprecated or obsoleted declaration. Useful to direct | |
users to replacement APIs. | |
Multiple availability attributes can be placed on a declaration, which may | |
correspond to different platforms. Only the availability attribute with the | |
platform corresponding to the target platform will be used; any others will be | |
ignored. If no availability attribute specifies availability for the current | |
target platform, the availability attributes are ignored. Supported platforms | |
are: | |
``ios`` | |
Apple's iOS operating system. The minimum deployment target is specified by | |
the ``-mios-version-min=*version*`` or ``-miphoneos-version-min=*version*`` | |
command-line arguments. | |
``macosx`` | |
Apple's Mac OS X operating system. The minimum deployment target is | |
specified by the ``-mmacosx-version-min=*version*`` command-line argument. | |
A declaration can be used even when deploying back to a platform version prior | |
to when the declaration was introduced. When this happens, the declaration is | |
`weakly linked | |
<https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html>`_, | |
as if the ``weak_import`` attribute were added to the declaration. A | |
weakly-linked declaration may or may not be present a run-time, and a program | |
can determine whether the declaration is present by checking whether the | |
address of that declaration is non-NULL. | |
If there are multiple declarations of the same entity, the availability | |
attributes must either match on a per-platform basis or later | |
declarations must not have availability attributes for that | |
platform. For example: | |
.. code-block:: c | |
void g(void) __attribute__((availability(macosx,introduced=10.4))); | |
void g(void) __attribute__((availability(macosx,introduced=10.4))); // okay, matches | |
void g(void) __attribute__((availability(ios,introduced=4.0))); // okay, adds a new platform | |
void g(void); // okay, inherits both macosx and ios availability from above. | |
void g(void) __attribute__((availability(macosx,introduced=10.5))); // error: mismatch | |
When one method overrides another, the overriding method can be more widely available than the overridden method, e.g.,: | |
.. code-block:: objc | |
@interface A | |
- (id)method __attribute__((availability(macosx,introduced=10.4))); | |
- (id)method2 __attribute__((availability(macosx,introduced=10.4))); | |
@end | |
@interface B : A | |
- (id)method __attribute__((availability(macosx,introduced=10.3))); // okay: method moved into base class later | |
- (id)method __attribute__((availability(macosx,introduced=10.5))); // error: this method was available via the base class in 10.4 | |
@end | |
_Noreturn | |
--------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"","","","X" | |
A function declared as ``_Noreturn`` shall not return to its caller. The | |
compiler will generate a diagnostic for a function declared as ``_Noreturn`` | |
that appears to be capable of returning to its caller. | |
noreturn | |
-------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"","X","","" | |
A function declared as ``[[noreturn]]`` shall not return to its caller. The | |
compiler will generate a diagnostic for a function declared as ``[[noreturn]]`` | |
that appears to be capable of returning to its caller. | |
carries_dependency | |
------------------ | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","X","","" | |
The ``carries_dependency`` attribute specifies dependency propagation into and | |
out of functions. | |
When specified on a function or Objective-C method, the ``carries_depedency`` | |
attribute means that the return value carries a dependency out of the function, | |
so that the implementation need not constrain ordering upon return from that | |
function. Implementations of the function and its caller may choose to preserve | |
dependencies instead of emitting memory ordering instructions such as fences. | |
Note, this attribute does not change the meaning of the program, but may result | |
in generatation of more efficient code. | |
enable_if | |
--------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
The ``enable_if`` attribute can be placed on function declarations to control | |
which overload is selected based on the values of the function's arguments. | |
When combined with the ``overloadable`` attribute, this feature is also | |
available in C. | |
.. code-block:: c++ | |
int isdigit(int c); | |
int isdigit(int c) __attribute__((enable_if(c <= -1 || c > 255, "chosen when 'c' is out of range"))) __attribute__((unavailable("'c' must have the value of an unsigned char or EOF"))); | |
void foo(char c) { | |
isdigit(c); | |
isdigit(10); | |
isdigit(-10); // results in a compile-time error. | |
} | |
The enable_if attribute takes two arguments, the first is an expression written | |
in terms of the function parameters, the second is a string explaining why this | |
overload candidate could not be selected to be displayed in diagnostics. The | |
expression is part of the function signature for the purposes of determining | |
whether it is a redeclaration (following the rules used when determining | |
whether a C++ template specialization is ODR-equivalent), but is not part of | |
the type. | |
The enable_if expression is evaluated as if it were the body of a | |
bool-returning constexpr function declared with the arguments of the function | |
it is being applied to, then called with the parameters at the callsite. If the | |
result is false or could not be determined through constant expression | |
evaluation, then this overload will not be chosen and the provided string may | |
be used in a diagnostic if the compile fails as a result. | |
Because the enable_if expression is an unevaluated context, there are no global | |
state changes, nor the ability to pass information from the enable_if | |
expression to the function body. For example, suppose we want calls to | |
strnlen(strbuf, maxlen) to resolve to strnlen_chk(strbuf, maxlen, size of | |
strbuf) only if the size of strbuf can be determined: | |
.. code-block:: c++ | |
__attribute__((always_inline)) | |
static inline size_t strnlen(const char *s, size_t maxlen) | |
__attribute__((overloadable)) | |
__attribute__((enable_if(__builtin_object_size(s, 0) != -1))), | |
"chosen when the buffer size is known but 'maxlen' is not"))) | |
{ | |
return strnlen_chk(s, maxlen, __builtin_object_size(s, 0)); | |
} | |
Multiple enable_if attributes may be applied to a single declaration. In this | |
case, the enable_if expressions are evaluated from left to right in the | |
following manner. First, the candidates whose enable_if expressions evaluate to | |
false or cannot be evaluated are discarded. If the remaining candidates do not | |
share ODR-equivalent enable_if expressions, the overload resolution is | |
ambiguous. Otherwise, enable_if overload resolution continues with the next | |
enable_if attribute on the candidates that have not been discarded and have | |
remaining enable_if attributes. In this way, we pick the most specific | |
overload out of a number of viable overloads using enable_if. | |
.. code-block:: c++ | |
void f() __attribute__((enable_if(true, ""))); // #1 | |
void f() __attribute__((enable_if(true, ""))) __attribute__((enable_if(true, ""))); // #2 | |
void g(int i, int j) __attribute__((enable_if(i, ""))); // #1 | |
void g(int i, int j) __attribute__((enable_if(j, ""))) __attribute__((enable_if(true))); // #2 | |
In this example, a call to f() is always resolved to #2, as the first enable_if | |
expression is ODR-equivalent for both declarations, but #1 does not have another | |
enable_if expression to continue evaluating, so the next round of evaluation has | |
only a single candidate. In a call to g(1, 1), the call is ambiguous even though | |
#2 has more enable_if attributes, because the first enable_if expressions are | |
not ODR-equivalent. | |
Query for this feature with ``__has_attribute(enable_if)``. | |
format (gnu::format) | |
-------------------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","X","","" | |
Clang supports the ``format`` attribute, which indicates that the function | |
accepts a ``printf`` or ``scanf``-like format string and corresponding | |
arguments or a ``va_list`` that contains these arguments. | |
Please see `GCC documentation about format attribute | |
<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ to find details | |
about attribute syntax. | |
Clang implements two kinds of checks with this attribute. | |
#. Clang checks that the function with the ``format`` attribute is called with | |
a format string that uses format specifiers that are allowed, and that | |
arguments match the format string. This is the ``-Wformat`` warning, it is | |
on by default. | |
#. Clang checks that the format string argument is a literal string. This is | |
the ``-Wformat-nonliteral`` warning, it is off by default. | |
Clang implements this mostly the same way as GCC, but there is a difference | |
for functions that accept a ``va_list`` argument (for example, ``vprintf``). | |
GCC does not emit ``-Wformat-nonliteral`` warning for calls to such | |
fuctions. Clang does not warn if the format string comes from a function | |
parameter, where the function is annotated with a compatible attribute, | |
otherwise it warns. For example: | |
.. code-block:: c | |
__attribute__((__format__ (__scanf__, 1, 3))) | |
void foo(const char* s, char *buf, ...) { | |
va_list ap; | |
va_start(ap, buf); | |
vprintf(s, ap); // warning: format string is not a string literal | |
} | |
In this case we warn because ``s`` contains a format string for a | |
``scanf``-like function, but it is passed to a ``printf``-like function. | |
If the attribute is removed, clang still warns, because the format string is | |
not a string literal. | |
Another example: | |
.. code-block:: c | |
__attribute__((__format__ (__printf__, 1, 3))) | |
void foo(const char* s, char *buf, ...) { | |
va_list ap; | |
va_start(ap, buf); | |
vprintf(s, ap); // warning | |
} | |
In this case Clang does not warn because the format string ``s`` and | |
the corresponding arguments are annotated. If the arguments are | |
incorrect, the caller of ``foo`` will receive a warning. | |
no_sanitize_address (no_address_safety_analysis, gnu::no_address_safety_analysis, gnu::no_sanitize_address) | |
----------------------------------------------------------------------------------------------------------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","X","","" | |
Use ``__attribute__((no_sanitize_address))`` on a function declaration to | |
specify that address safety instrumentation (e.g. AddressSanitizer) should | |
not be applied to that function. | |
no_sanitize_memory | |
------------------ | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
Use ``__attribute__((no_sanitize_memory))`` on a function declaration to | |
specify that checks for uninitialized memory should not be inserted | |
(e.g. by MemorySanitizer). The function may still be instrumented by the tool | |
to avoid false positives in other places. | |
no_sanitize_thread | |
------------------ | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
Use ``__attribute__((no_sanitize_thread))`` on a function declaration to | |
specify that checks for data races on plain (non-atomic) memory accesses should | |
not be inserted by ThreadSanitizer. The function is still instrumented by the | |
tool to avoid false positives and provide meaningful stack traces. | |
objc_method_family | |
------------------ | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
Many methods in Objective-C have conventional meanings determined by their | |
selectors. It is sometimes useful to be able to mark a method as having a | |
particular conventional meaning despite not having the right selector, or as | |
not having the conventional meaning that its selector would suggest. For these | |
use cases, we provide an attribute to specifically describe the "method family" | |
that a method belongs to. | |
**Usage**: ``__attribute__((objc_method_family(X)))``, where ``X`` is one of | |
``none``, ``alloc``, ``copy``, ``init``, ``mutableCopy``, or ``new``. This | |
attribute can only be placed at the end of a method declaration: | |
.. code-block:: objc | |
- (NSString *)initMyStringValue __attribute__((objc_method_family(none))); | |
Users who do not wish to change the conventional meaning of a method, and who | |
merely want to document its non-standard retain and release semantics, should | |
use the retaining behavior attributes (``ns_returns_retained``, | |
``ns_returns_not_retained``, etc). | |
Query for this feature with ``__has_attribute(objc_method_family)``. | |
objc_requires_super | |
------------------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
Some Objective-C classes allow a subclass to override a particular method in a | |
parent class but expect that the overriding method also calls the overridden | |
method in the parent class. For these cases, we provide an attribute to | |
designate that a method requires a "call to ``super``" in the overriding | |
method in the subclass. | |
**Usage**: ``__attribute__((objc_requires_super))``. This attribute can only | |
be placed at the end of a method declaration: | |
.. code-block:: objc | |
- (void)foo __attribute__((objc_requires_super)); | |
This attribute can only be applied the method declarations within a class, and | |
not a protocol. Currently this attribute does not enforce any placement of | |
where the call occurs in the overriding method (such as in the case of | |
``-dealloc`` where the call must appear at the end). It checks only that it | |
exists. | |
Note that on both OS X and iOS that the Foundation framework provides a | |
convenience macro ``NS_REQUIRES_SUPER`` that provides syntactic sugar for this | |
attribute: | |
.. code-block:: objc | |
- (void)foo NS_REQUIRES_SUPER; | |
This macro is conditionally defined depending on the compiler's support for | |
this attribute. If the compiler does not support the attribute the macro | |
expands to nothing. | |
Operationally, when a method has this annotation the compiler will warn if the | |
implementation of an override in a subclass does not call super. For example: | |
.. code-block:: objc | |
warning: method possibly missing a [super AnnotMeth] call | |
- (void) AnnotMeth{}; | |
^ | |
overloadable | |
------------ | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
Clang provides support for C++ function overloading in C. Function overloading | |
in C is introduced using the ``overloadable`` attribute. For example, one | |
might provide several overloaded versions of a ``tgsin`` function that invokes | |
the appropriate standard function computing the sine of a value with ``float``, | |
``double``, or ``long double`` precision: | |
.. code-block:: c | |
#include <math.h> | |
float __attribute__((overloadable)) tgsin(float x) { return sinf(x); } | |
double __attribute__((overloadable)) tgsin(double x) { return sin(x); } | |
long double __attribute__((overloadable)) tgsin(long double x) { return sinl(x); } | |
Given these declarations, one can call ``tgsin`` with a ``float`` value to | |
receive a ``float`` result, with a ``double`` to receive a ``double`` result, | |
etc. Function overloading in C follows the rules of C++ function overloading | |
to pick the best overload given the call arguments, with a few C-specific | |
semantics: | |
* Conversion from ``float`` or ``double`` to ``long double`` is ranked as a | |
floating-point promotion (per C99) rather than as a floating-point conversion | |
(as in C++). | |
* A conversion from a pointer of type ``T*`` to a pointer of type ``U*`` is | |
considered a pointer conversion (with conversion rank) if ``T`` and ``U`` are | |
compatible types. | |
* A conversion from type ``T`` to a value of type ``U`` is permitted if ``T`` | |
and ``U`` are compatible types. This conversion is given "conversion" rank. | |
The declaration of ``overloadable`` functions is restricted to function | |
declarations and definitions. Most importantly, if any function with a given | |
name is given the ``overloadable`` attribute, then all function declarations | |
and definitions with that name (and in that scope) must have the | |
``overloadable`` attribute. This rule even applies to redeclarations of | |
functions whose original declaration had the ``overloadable`` attribute, e.g., | |
.. code-block:: c | |
int f(int) __attribute__((overloadable)); | |
float f(float); // error: declaration of "f" must have the "overloadable" attribute | |
int g(int) __attribute__((overloadable)); | |
int g(int) { } // error: redeclaration of "g" must also have the "overloadable" attribute | |
Functions marked ``overloadable`` must have prototypes. Therefore, the | |
following code is ill-formed: | |
.. code-block:: c | |
int h() __attribute__((overloadable)); // error: h does not have a prototype | |
However, ``overloadable`` functions are allowed to use a ellipsis even if there | |
are no named parameters (as is permitted in C++). This feature is particularly | |
useful when combined with the ``unavailable`` attribute: | |
.. code-block:: c++ | |
void honeypot(...) __attribute__((overloadable, unavailable)); // calling me is an error | |
Functions declared with the ``overloadable`` attribute have their names mangled | |
according to the same rules as C++ function names. For example, the three | |
``tgsin`` functions in our motivating example get the mangled names | |
``_Z5tgsinf``, ``_Z5tgsind``, and ``_Z5tgsine``, respectively. There are two | |
caveats to this use of name mangling: | |
* Future versions of Clang may change the name mangling of functions overloaded | |
in C, so you should not depend on an specific mangling. To be completely | |
safe, we strongly urge the use of ``static inline`` with ``overloadable`` | |
functions. | |
* The ``overloadable`` attribute has almost no meaning when used in C++, | |
because names will already be mangled and functions are already overloadable. | |
However, when an ``overloadable`` function occurs within an ``extern "C"`` | |
linkage specification, it's name *will* be mangled in the same way as it | |
would in C. | |
Query for this feature with ``__has_extension(attribute_overloadable)``. | |
Variable Attributes | |
=================== | |
tls_model (gnu::tls_model) | |
-------------------------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","X","","" | |
The ``tls_model`` attribute allows you to specify which thread-local storage | |
model to use. It accepts the following strings: | |
* global-dynamic | |
* local-dynamic | |
* initial-exec | |
* local-exec | |
TLS models are mutually exclusive. | |
Statement Attributes | |
==================== | |
fallthrough (clang::fallthrough) | |
-------------------------------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"","X","","" | |
The ``clang::fallthrough`` attribute is used along with the | |
``-Wimplicit-fallthrough`` argument to annotate intentional fall-through | |
between switch labels. It can only be applied to a null statement placed at a | |
point of execution between any statement and the next switch label. It is | |
common to mark these places with a specific comment, but this attribute is | |
meant to replace comments with a more strict annotation, which can be checked | |
by the compiler. This attribute doesn't change semantics of the code and can | |
be used wherever an intended fall-through occurs. It is designed to mimic | |
control-flow statements like ``break;``, so it can be placed in most places | |
where ``break;`` can, but only if there are no statements on the execution path | |
between it and the next switch label. | |
Here is an example: | |
.. code-block:: c++ | |
// compile with -Wimplicit-fallthrough | |
switch (n) { | |
case 22: | |
case 33: // no warning: no statements between case labels | |
f(); | |
case 44: // warning: unannotated fall-through | |
g(); | |
[[clang::fallthrough]]; | |
case 55: // no warning | |
if (x) { | |
h(); | |
break; | |
} | |
else { | |
i(); | |
[[clang::fallthrough]]; | |
} | |
case 66: // no warning | |
p(); | |
[[clang::fallthrough]]; // warning: fallthrough annotation does not | |
// directly precede case label | |
q(); | |
case 77: // warning: unannotated fall-through | |
r(); | |
} | |
Consumed Annotation Checking | |
============================ | |
Clang supports additional attributes for checking basic resource management | |
properties, specifically for unique objects that have a single owning reference. | |
The following attributes are currently supported, although **the implementation | |
for these annotations is currently in development and are subject to change.** | |
callable_when | |
------------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
Use ``__attribute__((callable_when(...)))`` to indicate what states a method | |
may be called in. Valid states are unconsumed, consumed, or unknown. Each | |
argument to this attribute must be a quoted string. E.g.: | |
``__attribute__((callable_when("unconsumed", "unknown")))`` | |
consumable | |
---------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
Each ``class`` that uses any of the typestate annotations must first be marked | |
using the ``consumable`` attribute. Failure to do so will result in a warning. | |
This attribute accepts a single parameter that must be one of the following: | |
``unknown``, ``consumed``, or ``unconsumed``. | |
param_typestate | |
--------------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
This attribute specifies expectations about function parameters. Calls to an | |
function with annotated parameters will issue a warning if the corresponding | |
argument isn't in the expected state. The attribute is also used to set the | |
initial state of the parameter when analyzing the function's body. | |
return_typestate | |
---------------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
The ``return_typestate`` attribute can be applied to functions or parameters. | |
When applied to a function the attribute specifies the state of the returned | |
value. The function's body is checked to ensure that it always returns a value | |
in the specified state. On the caller side, values returned by the annotated | |
function are initialized to the given state. | |
When applied to a function parameter it modifies the state of an argument after | |
a call to the function returns. The function's body is checked to ensure that | |
the parameter is in the expected state before returning. | |
set_typestate | |
------------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
Annotate methods that transition an object into a new state with | |
``__attribute__((set_typestate(new_state)))``. The new new state must be | |
unconsumed, consumed, or unknown. | |
test_typestate | |
-------------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
Use ``__attribute__((test_typestate(tested_state)))`` to indicate that a method | |
returns true if the object is in the specified state.. | |
Type Safety Checking | |
==================== | |
Clang supports additional attributes to enable checking type safety properties | |
that can't be enforced by the C type system. Use cases include: | |
* MPI library implementations, where these attributes enable checking that | |
the buffer type matches the passed ``MPI_Datatype``; | |
* for HDF5 library there is a similar use case to MPI; | |
* checking types of variadic functions' arguments for functions like | |
``fcntl()`` and ``ioctl()``. | |
You can detect support for these attributes with ``__has_attribute()``. For | |
example: | |
.. code-block:: c++ | |
#if defined(__has_attribute) | |
# if __has_attribute(argument_with_type_tag) && \ | |
__has_attribute(pointer_with_type_tag) && \ | |
__has_attribute(type_tag_for_datatype) | |
# define ATTR_MPI_PWT(buffer_idx, type_idx) __attribute__((pointer_with_type_tag(mpi,buffer_idx,type_idx))) | |
/* ... other macros ... */ | |
# endif | |
#endif | |
#if !defined(ATTR_MPI_PWT) | |
# define ATTR_MPI_PWT(buffer_idx, type_idx) | |
#endif | |
int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */) | |
ATTR_MPI_PWT(1,3); | |
argument_with_type_tag | |
---------------------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
Use ``__attribute__((argument_with_type_tag(arg_kind, arg_idx, | |
type_tag_idx)))`` on a function declaration to specify that the function | |
accepts a type tag that determines the type of some other argument. | |
``arg_kind`` is an identifier that should be used when annotating all | |
applicable type tags. | |
This attribute is primarily useful for checking arguments of variadic functions | |
(``pointer_with_type_tag`` can be used in most non-variadic cases). | |
For example: | |
.. code-block:: c++ | |
int fcntl(int fd, int cmd, ...) | |
__attribute__(( argument_with_type_tag(fcntl,3,2) )); | |
pointer_with_type_tag | |
--------------------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
Use ``__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))`` | |
on a function declaration to specify that the function accepts a type tag that | |
determines the pointee type of some other pointer argument. | |
For example: | |
.. code-block:: c++ | |
int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */) | |
__attribute__(( pointer_with_type_tag(mpi,1,3) )); | |
type_tag_for_datatype | |
--------------------- | |
.. csv-table:: Supported Syntaxes | |
:header: "GNU", "C++11", "__declspec", "Keyword" | |
"X","","","" | |
Clang supports annotating type tags of two forms. | |
* **Type tag that is an expression containing a reference to some declared | |
identifier.** Use ``__attribute__((type_tag_for_datatype(kind, type)))`` on a | |
declaration with that identifier: | |
.. code-block:: c++ | |
extern struct mpi_datatype mpi_datatype_int | |
__attribute__(( type_tag_for_datatype(mpi,int) )); | |
#define MPI_INT ((MPI_Datatype) &mpi_datatype_int) | |
* **Type tag that is an integral literal.** Introduce a ``static const`` | |
variable with a corresponding initializer value and attach | |
``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration, | |
for example: | |
.. code-block:: c++ | |
#define MPI_INT ((MPI_Datatype) 42) | |
static const MPI_Datatype mpi_datatype_int | |
__attribute__(( type_tag_for_datatype(mpi,int) )) = 42 | |
The attribute also accepts an optional third argument that determines how the | |
expression is compared to the type tag. There are two supported flags: | |
* ``layout_compatible`` will cause types to be compared according to | |
layout-compatibility rules (C++11 [class.mem] p 17, 18). This is | |
implemented to support annotating types like ``MPI_DOUBLE_INT``. | |
For example: | |
.. code-block:: c++ | |
/* In mpi.h */ | |
struct internal_mpi_double_int { double d; int i; }; | |
extern struct mpi_datatype mpi_datatype_double_int | |
__attribute__(( type_tag_for_datatype(mpi, struct internal_mpi_double_int, layout_compatible) )); | |
#define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int) | |
/* In user code */ | |
struct my_pair { double a; int b; }; | |
struct my_pair *buffer; | |
MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning | |
struct my_int_pair { int a; int b; } | |
struct my_int_pair *buffer2; | |
MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning: actual buffer element | |
// type 'struct my_int_pair' | |
// doesn't match specified MPI_Datatype | |
* ``must_be_null`` specifies that the expression should be a null pointer | |
constant, for example: | |
.. code-block:: c++ | |
/* In mpi.h */ | |
extern struct mpi_datatype mpi_datatype_null | |
__attribute__(( type_tag_for_datatype(mpi, void, must_be_null) )); | |
#define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null) | |
/* In user code */ | |
MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL | |
// was specified but buffer | |
// is not a null pointer | |