Skip to content
Snippets Groups Projects
LanguageExtensions.rst 69.7 KiB
Newer Older
conversion operator in that closure type that produces a block pointer with the
same signature as the lambda itself, e.g.,

.. code-block:: objc

  operator NSComparisonResult (^)(id, id)() const;

This conversion function returns a new block that simply forwards the two
parameters to the lambda object (which it captures by copy), then returns the
result.  The returned block is first copied (with ``Block_copy``) and then
autoreleased.  As an optimization, if a lambda expression is immediately
converted to a block pointer (as in the first example, above), then the block
is not copied and autoreleased: rather, it is given the same lifetime as a
block literal written at that point in the program, which avoids the overhead
of copying a block to the heap in the common case.

The conversion from a lambda to a block pointer is only available in
Objective-C++, and not in C++ with blocks, due to its use of Objective-C memory
management (autorelease).

Object Literals and Subscripting
--------------------------------

Clang provides support for :doc:`Object Literals and Subscripting
<ObjectiveCLiterals>` in Objective-C, which simplifies common Objective-C
programming patterns, makes programs more concise, and improves the safety of
container creation.  There are several feature macros associated with object
literals and subscripting: ``__has_feature(objc_array_literals)`` tests the
availability of array literals; ``__has_feature(objc_dictionary_literals)``
tests the availability of dictionary literals;
``__has_feature(objc_subscripting)`` tests the availability of object
subscripting.

Objective-C Autosynthesis of Properties
---------------------------------------

Clang provides support for autosynthesis of declared properties.  Using this
feature, clang provides default synthesis of those properties not declared
@dynamic and not having user provided backing getter and setter methods.
``__has_feature(objc_default_synthesize_properties)`` checks for availability
of this feature in version of clang being used.

.. _langext-objc_method_family:

The ``objc_method_family`` attribute
------------------------------------

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 :ref:`retaining behavior attributes <langext-objc-retain-release>`
described below.

Query for this feature with ``__has_attribute(objc_method_family)``.

.. _langext-objc-retain-release:

Objective-C retaining behavior attributes
-----------------------------------------

In Objective-C, functions and methods are generally assumed to follow the
`Cocoa Memory Management 
<http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html>`_
conventions for ownership of object arguments and
return values. However, there are exceptions, and so Clang provides attributes
to allow these exceptions to be documented. This are used by ARC and the
`static analyzer <http://clang-analyzer.llvm.org>`_ Some exceptions may be
better described using the :ref:`objc_method_family
<langext-objc_method_family>` attribute instead.

**Usage**: The ``ns_returns_retained``, ``ns_returns_not_retained``,
``ns_returns_autoreleased``, ``cf_returns_retained``, and
``cf_returns_not_retained`` attributes can be placed on methods and functions
that return Objective-C or CoreFoundation objects. They are commonly placed at
the end of a function prototype or method declaration:

.. code-block:: objc

  id foo() __attribute__((ns_returns_retained));

  - (NSString *)bar:(int)x __attribute__((ns_returns_retained));

The ``*_returns_retained`` attributes specify that the returned object has a +1
retain count.  The ``*_returns_not_retained`` attributes specify that the return
object has a +0 retain count, even if the normal convention for its selector
would be +1.  ``ns_returns_autoreleased`` specifies that the returned object is
+0, but is guaranteed to live at least as long as the next flush of an
autorelease pool.

**Usage**: The ``ns_consumed`` and ``cf_consumed`` attributes can be placed on
an parameter declaration; they specify that the argument is expected to have a
+1 retain count, which will be balanced in some way by the function or method.
The ``ns_consumes_self`` attribute can only be placed on an Objective-C
method; it specifies that the method expects its ``self`` parameter to have a
+1 retain count, which it will balance in some way.

.. code-block:: objc

  void foo(__attribute__((ns_consumed)) NSString *string);

  - (void) bar __attribute__((ns_consumes_self));
  - (void) baz:(id) __attribute__((ns_consumed)) x;

Further examples of these attributes are available in the static analyzer's `list of annotations for analysis
<http://clang-analyzer.llvm.org/annotations.html#cocoa_mem>`_.

Query for these features with ``__has_attribute(ns_consumed)``,
``__has_attribute(ns_returns_retained)``, etc.


Function Overloading in C
=========================

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)``.

Initializer lists for complex numbers in C
==========================================

clang supports an extension which allows the following in C:

.. code-block:: c++

  #include <math.h>
  #include <complex.h>
  complex float x = { 1.0f, INFINITY }; // Init to (1, Inf)

This construct is useful because there is no way to separately initialize the
real and imaginary parts of a complex variable in standard C, given that clang
does not support ``_Imaginary``.  (Clang also supports the ``__real__`` and
``__imag__`` extensions from gcc, which help in some cases, but are not usable
in static initializers.)

Note that this extension does not allow eliding the braces; the meaning of the
following two lines is different:

.. code-block:: c++

  complex float x[] = { { 1.0f, 1.0f } }; // [0] = (1, 1)
  complex float x[] = { 1.0f, 1.0f }; // [0] = (1, 0), [1] = (1, 0)

This extension also works in C++ mode, as far as that goes, but does not apply
to the C++ ``std::complex``.  (In C++11, list initialization allows the same
syntax to be used with ``std::complex`` with the same meaning.)

Builtin Functions
=================

Clang supports a number of builtin library functions with the same syntax as
GCC, including things like ``__builtin_nan``, ``__builtin_constant_p``,
``__builtin_choose_expr``, ``__builtin_types_compatible_p``,
``__sync_fetch_and_add``, etc.  In addition to the GCC builtins, Clang supports
a number of builtins that GCC does not, which are listed here.

Please note that Clang does not and will not support all of the GCC builtins
for vector operations.  Instead of using builtins, you should use the functions
defined in target-specific header files like ``<xmmintrin.h>``, which define
portable wrappers for these.  Many of the Clang versions of these functions are
implemented directly in terms of :ref:`extended vector support
<langext-vectors>` instead of builtins, in order to reduce the number of
builtins that we need to implement.

``__builtin_readcyclecounter``
------------------------------

``__builtin_readcyclecounter`` is used to access the cycle counter register (or
a similar low-latency, high-accuracy clock) on those targets that support it.

**Syntax**:

.. code-block:: c++

  __builtin_readcyclecounter()

**Example of Use**:

.. code-block:: c++

  unsigned long long t0 = __builtin_readcyclecounter();
  do_something();
  unsigned long long t1 = __builtin_readcyclecounter();
  unsigned long long cycles_to_do_something = t1 - t0; // assuming no overflow

**Description**:

The ``__builtin_readcyclecounter()`` builtin returns the cycle counter value,
which may be either global or process/thread-specific depending on the target.
As the backing counters often overflow quickly (on the order of seconds) this
should only be used for timing small intervals.  When not supported by the
target, the return value is always zero.  This builtin takes no arguments and
produces an unsigned long long result.

Query for this feature with ``__has_builtin(__builtin_readcyclecounter)``.

.. _langext-__builtin_shufflevector:

``__builtin_shufflevector``
---------------------------

``__builtin_shufflevector`` is used to express generic vector
permutation/shuffle/swizzle operations.  This builtin is also very important
for the implementation of various target-specific header files like
``<xmmintrin.h>``.

**Syntax**:

.. code-block:: c++

  __builtin_shufflevector(vec1, vec2, index1, index2, ...)

**Examples**:

.. code-block:: c++

  // Identity operation - return 4-element vector V1.
  __builtin_shufflevector(V1, V1, 0, 1, 2, 3)

  // "Splat" element 0 of V1 into a 4-element result.
  __builtin_shufflevector(V1, V1, 0, 0, 0, 0)

  // Reverse 4-element vector V1.
  __builtin_shufflevector(V1, V1, 3, 2, 1, 0)

  // Concatenate every other element of 4-element vectors V1 and V2.
  __builtin_shufflevector(V1, V2, 0, 2, 4, 6)

  // Concatenate every other element of 8-element vectors V1 and V2.
  __builtin_shufflevector(V1, V2, 0, 2, 4, 6, 8, 10, 12, 14)

**Description**:

The first two arguments to ``__builtin_shufflevector`` are vectors that have
the same element type.  The remaining arguments are a list of integers that
specify the elements indices of the first two vectors that should be extracted
and returned in a new vector.  These element indices are numbered sequentially
starting with the first vector, continuing into the second vector.  Thus, if
``vec1`` is a 4-element vector, index 5 would refer to the second element of
``vec2``.

The result of ``__builtin_shufflevector`` is a vector with the same element
type as ``vec1``/``vec2`` but that has an element count equal to the number of
indices specified.

Query for this feature with ``__has_builtin(__builtin_shufflevector)``.

``__builtin_unreachable``
-------------------------

``__builtin_unreachable`` is used to indicate that a specific point in the
program cannot be reached, even if the compiler might otherwise think it can.
This is useful to improve optimization and eliminates certain warnings.  For
example, without the ``__builtin_unreachable`` in the example below, the
compiler assumes that the inline asm can fall through and prints a "function
declared '``noreturn``' should not return" warning.

**Syntax**:

.. code-block:: c++

    __builtin_unreachable()

**Example of use**:

.. code-block:: c++

  void myabort(void) __attribute__((noreturn));
  void myabort(void) {
    asm("int3");
    __builtin_unreachable();
  }

**Description**:

The ``__builtin_unreachable()`` builtin has completely undefined behavior.
Since it has undefined behavior, it is a statement that it is never reached and
the optimizer can take advantage of this to produce better code.  This builtin
takes no arguments and produces a void result.

Query for this feature with ``__has_builtin(__builtin_unreachable)``.

``__sync_swap``
---------------

``__sync_swap`` is used to atomically swap integers or pointers in memory.

**Syntax**:

.. code-block:: c++

  type __sync_swap(type *ptr, type value, ...)

**Example of Use**:

.. code-block:: c++

  int old_value = __sync_swap(&value, new_value);

**Description**:

The ``__sync_swap()`` builtin extends the existing ``__sync_*()`` family of
atomic intrinsics to allow code to atomically swap the current value with the
new value.  More importantly, it helps developers write more efficient and
correct code by avoiding expensive loops around
``__sync_bool_compare_and_swap()`` or relying on the platform specific
implementation details of ``__sync_lock_test_and_set()``.  The
``__sync_swap()`` builtin is a full barrier.

Multiprecision Arithmetic Builtins
----------------------------------

Clang provides a set of builtins which expose multiprecision arithmetic in a
manner amenable to C. They all have the following form:

.. code-block:: c

  unsigned x = ..., y = ..., carryin = ..., carryout;
  unsigned sum = __builtin_addc(x, y, carryin, &carryout);

Thus one can form a multiprecision addition chain in the following manner:

.. code-block:: c

  unsigned *x, *y, *z, carryin=0, carryout;
  z[0] = __builtin_addc(x[0], y[0], carryin, &carryout);
  carryin = carryout;
  z[1] = __builtin_addc(x[1], y[1], carryin, &carryout);
  carryin = carryout;
  z[2] = __builtin_addc(x[2], y[2], carryin, &carryout);
  carryin = carryout;
  z[3] = __builtin_addc(x[3], y[3], carryin, &carryout);

The complete list of builtins are:

.. code-block:: c

  unsigned short     __builtin_addcs (unsigned short x, unsigned short y, unsigned short carryin, unsigned short *carryout);
  unsigned           __builtin_addc  (unsigned x, unsigned y, unsigned carryin, unsigned *carryout);
  unsigned long      __builtin_addcl (unsigned long x, unsigned long y, unsigned long carryin, unsigned long *carryout);
  unsigned long long __builtin_addcll(unsigned long long x, unsigned long long y, unsigned long long carryin, unsigned long long *carryout);
  unsigned short     __builtin_subcs (unsigned short x, unsigned short y, unsigned short carryin, unsigned short *carryout);
  unsigned           __builtin_subc  (unsigned x, unsigned y, unsigned carryin, unsigned *carryout);
  unsigned long      __builtin_subcl (unsigned long x, unsigned long y, unsigned long carryin, unsigned long *carryout);
  unsigned long long __builtin_subcll(unsigned long long x, unsigned long long y, unsigned long long carryin, unsigned long long *carryout);

.. _langext-__c11_atomic:

__c11_atomic builtins
---------------------

Clang provides a set of builtins which are intended to be used to implement
C11's ``<stdatomic.h>`` header.  These builtins provide the semantics of the
``_explicit`` form of the corresponding C11 operation, and are named with a
``__c11_`` prefix.  The supported operations are:

* ``__c11_atomic_init``
* ``__c11_atomic_thread_fence``
* ``__c11_atomic_signal_fence``
* ``__c11_atomic_is_lock_free``
* ``__c11_atomic_store``
* ``__c11_atomic_load``
* ``__c11_atomic_exchange``
* ``__c11_atomic_compare_exchange_strong``
* ``__c11_atomic_compare_exchange_weak``
* ``__c11_atomic_fetch_add``
* ``__c11_atomic_fetch_sub``
* ``__c11_atomic_fetch_and``
* ``__c11_atomic_fetch_or``
* ``__c11_atomic_fetch_xor``

Non-standard C++11 Attributes
=============================

Clang supports one non-standard C++11 attribute.  It resides in the ``clang``
attribute namespace.

The ``clang::fallthrough`` attribute
------------------------------------

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();
  }

Target-Specific Extensions
==========================

Clang supports some language features conditionally on some targets.

X86/X86-64 Language Extensions
------------------------------

The X86 backend has these language extensions:

Memory references off the GS segment
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Annotating a pointer with address space #256 causes it to be code generated
relative to the X86 GS segment register, and address space #257 causes it to be
relative to the X86 FS segment.  Note that this is a very very low-level
feature that should only be used if you know what you're doing (for example in
an OS kernel).

Here is an example:

.. code-block:: c++

  #define GS_RELATIVE __attribute__((address_space(256)))
  int foo(int GS_RELATIVE *P) {
    return *P;
  }

Which compiles to (on X86-32):

.. code-block:: gas

  _foo:
          movl    4(%esp), %eax
          movl    %gs:(%eax), %eax
          ret


Clang supports additional attributes that are useful for documenting program
invariants and rules for static analysis tools, such as the `Clang Static
Analyzer <http://clang-analyzer.llvm.org/>`_. These attributes are documented
in the analyzer's `list of source-level annotations
<http://clang-analyzer.llvm.org/annotations.html>`_.

.. _langext-address_sanitizer:

AddressSanitizer
----------------

Use ``__has_feature(address_sanitizer)`` to check if the code is being built

Use ``__attribute__((no_address_safety_analysis))`` on a function declaration
to specify that address safety instrumentation (e.g. AddressSanitizer) should
not be applied to that function.

Thread-Safety Annotation Checking
=================================

Clang supports additional attributes for checking basic locking policies in
multithreaded programs.  Clang currently parses the following list of
attributes, although **the implementation for these annotations is currently in
development.** For more details, see the `GCC implementation
<http://gcc.gnu.org/wiki/ThreadSafetyAnnotation>`_.

``no_thread_safety_analysis``
-----------------------------

Use ``__attribute__((no_thread_safety_analysis))`` on a function declaration to
specify that the thread safety analysis should not be run on that function.
This attribute provides an escape hatch (e.g. for situations when it is
difficult to annotate the locking policy).

``lockable``
------------

Use ``__attribute__((lockable))`` on a class definition to specify that it has
a lockable type (e.g. a Mutex class).  This annotation is primarily used to
check consistency.

``scoped_lockable``
-------------------

Use ``__attribute__((scoped_lockable))`` on a class definition to specify that
it has a "scoped" lockable type.  Objects of this type will acquire the lock
upon construction and release it upon going out of scope.  This annotation is
primarily used to check consistency.

``guarded_var``
---------------

Use ``__attribute__((guarded_var))`` on a variable declaration to specify that
the variable must be accessed while holding some lock.

``pt_guarded_var``
------------------

Use ``__attribute__((pt_guarded_var))`` on a pointer declaration to specify
that the pointer must be dereferenced while holding some lock.

``guarded_by(l)``
-----------------

Use ``__attribute__((guarded_by(l)))`` on a variable declaration to specify
that the variable must be accessed while holding lock ``l``.

``pt_guarded_by(l)``
--------------------

Use ``__attribute__((pt_guarded_by(l)))`` on a pointer declaration to specify
that the pointer must be dereferenced while holding lock ``l``.

``acquired_before(...)``
------------------------

Use ``__attribute__((acquired_before(...)))`` on a declaration of a lockable
variable to specify that the lock must be acquired before all attribute
arguments.  Arguments must be lockable type, and there must be at least one
argument.

``acquired_after(...)``
-----------------------

Use ``__attribute__((acquired_after(...)))`` on a declaration of a lockable
variable to specify that the lock must be acquired after all attribute
arguments.  Arguments must be lockable type, and there must be at least one
argument.

``exclusive_lock_function(...)``
--------------------------------

Use ``__attribute__((exclusive_lock_function(...)))`` on a function declaration
to specify that the function acquires all listed locks exclusively.  This
attribute takes zero or more arguments: either of lockable type or integers
indexing into function parameters of lockable type.  If no arguments are given,
the acquired lock is implicitly ``this`` of the enclosing object.

``shared_lock_function(...)``
-----------------------------

Use ``__attribute__((shared_lock_function(...)))`` on a function declaration to
specify that the function acquires all listed locks, although the locks may be
shared (e.g. read locks).  This attribute takes zero or more arguments: either
of lockable type or integers indexing into function parameters of lockable
type.  If no arguments are given, the acquired lock is implicitly ``this`` of
the enclosing object.

``exclusive_trylock_function(...)``
-----------------------------------

Use ``__attribute__((exclusive_lock_function(...)))`` on a function declaration
to specify that the function will try (without blocking) to acquire all listed
locks exclusively.  This attribute takes one or more arguments.  The first
argument is an integer or boolean value specifying the return value of a
successful lock acquisition.  The remaining arugments are either of lockable
type or integers indexing into function parameters of lockable type.  If only
one argument is given, the acquired lock is implicitly ``this`` of the
enclosing object.

``shared_trylock_function(...)``
--------------------------------

Use ``__attribute__((shared_lock_function(...)))`` on a function declaration to
specify that the function will try (without blocking) to acquire all listed
locks, although the locks may be shared (e.g. read locks).  This attribute
takes one or more arguments.  The first argument is an integer or boolean value
specifying the return value of a successful lock acquisition.  The remaining
arugments are either of lockable type or integers indexing into function
parameters of lockable type.  If only one argument is given, the acquired lock
is implicitly ``this`` of the enclosing object.

``unlock_function(...)``
------------------------

Use ``__attribute__((unlock_function(...)))`` on a function declaration to
specify that the function release all listed locks.  This attribute takes zero
or more arguments: either of lockable type or integers indexing into function
parameters of lockable type.  If no arguments are given, the acquired lock is
implicitly ``this`` of the enclosing object.

``lock_returned(l)``
--------------------

Use ``__attribute__((lock_returned(l)))`` on a function declaration to specify
that the function returns lock ``l`` (``l`` must be of lockable type).  This
annotation is used to aid in resolving lock expressions.

``locks_excluded(...)``
-----------------------

Use ``__attribute__((locks_excluded(...)))`` on a function declaration to
specify that the function must not be called with the listed locks.  Arguments
must be lockable type, and there must be at least one argument.

``exclusive_locks_required(...)``
---------------------------------

Use ``__attribute__((exclusive_locks_required(...)))`` on a function
declaration to specify that the function must be called while holding the
listed exclusive locks.  Arguments must be lockable type, and there must be at
least one argument.

``shared_locks_required(...)``
------------------------------

Use ``__attribute__((shared_locks_required(...)))`` on a function declaration
to specify that the function must be called while holding the listed shared
locks.  Arguments must be lockable type, and there must be at least one
argument.

Type Safety Checking
====================

Clang supports additional attributes to enable checking type safety properties
that can't be enforced by C type system.  Usecases include:

* MPI library implementations, where these attributes enable checking that
  buffer type matches the passed ``MPI_Datatype``;
* for HDF5 library there is a similar usecase as 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(...)``
-------------------------------

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 of 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(...)``
------------------------------

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(...)``
------------------------------

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

Format String Checking
======================

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 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 it to a ``printf``-like function.

   If the attribute is removed, clang still warns, because the format string is
   not a string literal.

   But in this case Clang does not warn because the format string ``s`` and
   corresponding arguments are annotated.  If the arguments are incorrect,
   caller of ``foo`` will get a warning.

   .. 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
     }