returns true if the object is in the specified state..\r
\r
\r
+Type Safety Checking\r
+====================\r
+Clang supports additional attributes to enable checking type safety properties\r
+that can't be enforced by the C type system. Use cases include:\r
+\r
+* MPI library implementations, where these attributes enable checking that\r
+ the buffer type matches the passed ``MPI_Datatype``;\r
+* for HDF5 library there is a similar use case to MPI;\r
+* checking types of variadic functions' arguments for functions like\r
+ ``fcntl()`` and ``ioctl()``.\r
+\r
+You can detect support for these attributes with ``__has_attribute()``. For\r
+example:\r
+\r
+.. code-block:: c++\r
+\r
+ #if defined(__has_attribute)\r
+ # if __has_attribute(argument_with_type_tag) && \\r
+ __has_attribute(pointer_with_type_tag) && \\r
+ __has_attribute(type_tag_for_datatype)\r
+ # define ATTR_MPI_PWT(buffer_idx, type_idx) __attribute__((pointer_with_type_tag(mpi,buffer_idx,type_idx)))\r
+ /* ... other macros ... */\r
+ # endif\r
+ #endif\r
+\r
+ #if !defined(ATTR_MPI_PWT)\r
+ # define ATTR_MPI_PWT(buffer_idx, type_idx)\r
+ #endif\r
+\r
+ int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)\r
+ ATTR_MPI_PWT(1,3);\r
+\r
+argument_with_type_tag\r
+----------------------\r
+.. csv-table:: Supported Syntaxes\r
+ :header: "GNU", "C++11", "__declspec", "Keyword"\r
+\r
+ "X","","",""\r
+\r
+Use ``__attribute__((argument_with_type_tag(arg_kind, arg_idx,\r
+type_tag_idx)))`` on a function declaration to specify that the function\r
+accepts a type tag that determines the type of some other argument.\r
+``arg_kind`` is an identifier that should be used when annotating all\r
+applicable type tags.\r
+\r
+This attribute is primarily useful for checking arguments of variadic functions\r
+(``pointer_with_type_tag`` can be used in most non-variadic cases).\r
+\r
+For example:\r
+\r
+.. code-block:: c++\r
+\r
+ int fcntl(int fd, int cmd, ...)\r
+ __attribute__(( argument_with_type_tag(fcntl,3,2) ));\r
+\r
+\r
+pointer_with_type_tag\r
+---------------------\r
+.. csv-table:: Supported Syntaxes\r
+ :header: "GNU", "C++11", "__declspec", "Keyword"\r
+\r
+ "X","","",""\r
+\r
+Use ``__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))``\r
+on a function declaration to specify that the function accepts a type tag that\r
+determines the pointee type of some other pointer argument.\r
+\r
+For example:\r
+\r
+.. code-block:: c++\r
+\r
+ int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)\r
+ __attribute__(( pointer_with_type_tag(mpi,1,3) ));\r
+\r
+\r
+type_tag_for_datatype\r
+---------------------\r
+.. csv-table:: Supported Syntaxes\r
+ :header: "GNU", "C++11", "__declspec", "Keyword"\r
+\r
+ "X","","",""\r
+\r
+Clang supports annotating type tags of two forms.\r
+\r
+* **Type tag that is an expression containing a reference to some declared\r
+ identifier.** Use ``__attribute__((type_tag_for_datatype(kind, type)))`` on a\r
+ declaration with that identifier:\r
+\r
+ .. code-block:: c++\r
+\r
+ extern struct mpi_datatype mpi_datatype_int\r
+ __attribute__(( type_tag_for_datatype(mpi,int) ));\r
+ #define MPI_INT ((MPI_Datatype) &mpi_datatype_int)\r
+\r
+* **Type tag that is an integral literal.** Introduce a ``static const``\r
+ variable with a corresponding initializer value and attach\r
+ ``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration,\r
+ for example:\r
+\r
+ .. code-block:: c++\r
+\r
+ #define MPI_INT ((MPI_Datatype) 42)\r
+ static const MPI_Datatype mpi_datatype_int\r
+ __attribute__(( type_tag_for_datatype(mpi,int) )) = 42\r
+\r
+The attribute also accepts an optional third argument that determines how the\r
+expression is compared to the type tag. There are two supported flags:\r
+\r
+* ``layout_compatible`` will cause types to be compared according to\r
+ layout-compatibility rules (C++11 [class.mem] p 17, 18). This is\r
+ implemented to support annotating types like ``MPI_DOUBLE_INT``.\r
+\r
+ For example:\r
+\r
+ .. code-block:: c++\r
+\r
+ /* In mpi.h */\r
+ struct internal_mpi_double_int { double d; int i; };\r
+ extern struct mpi_datatype mpi_datatype_double_int\r
+ __attribute__(( type_tag_for_datatype(mpi, struct internal_mpi_double_int, layout_compatible) ));\r
+\r
+ #define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int)\r
+\r
+ /* In user code */\r
+ struct my_pair { double a; int b; };\r
+ struct my_pair *buffer;\r
+ MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning\r
+\r
+ struct my_int_pair { int a; int b; }\r
+ struct my_int_pair *buffer2;\r
+ MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning: actual buffer element\r
+ // type 'struct my_int_pair'\r
+ // doesn't match specified MPI_Datatype\r
+\r
+* ``must_be_null`` specifies that the expression should be a null pointer\r
+ constant, for example:\r
+\r
+ .. code-block:: c++\r
+\r
+ /* In mpi.h */\r
+ extern struct mpi_datatype mpi_datatype_null\r
+ __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) ));\r
+\r
+ #define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null)\r
+\r
+ /* In user code */\r
+ MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL\r
+ // was specified but buffer\r
+ // is not a null pointer\r
+\r
+\r
Use ``__has_feature(memory_sanitizer)`` to check if the code is being built
with :doc:`MemorySanitizer`.
-Thread Safety Analysis
-======================
-
-Clang Thread Safety Analysis is a C++ language extension which warns about
-potential race conditions in code. The analysis works very much like a type
-system for multi-threaded programs. In addition to declaring the *type* of
-data (e.g. ``int``, ``float``, etc.), the programmer can (optionally) declare
-how access to that data is controlled in a multi-threaded environment. The
-compiler will then issue warnings whenever code fails to follow obey the
-declared requirements.
-
-The complete list of thread safety attributes, along with examples and
-frequently asked questions, can be found in the main documentation: see
-:doc:`ThreadSafetyAnalysis`.
-
-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(...)``
--------------------------------
-
-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(...)``
-------------------------------
-
-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
======================
UnsignedArgument<"TypeTagIdx">,
BoolArgument<"IsPointer">];
let HasCustomParsing = 1;
- let Documentation = [Undocumented];
+ let Documentation = [ArgumentWithTypeTagDocs, PointerWithTypeTagDocs];
}
def TypeTagForDatatype : InheritableAttr {
BoolArgument<"MustBeNull">];
// let Subjects = SubjectList<[Var], ErrorDiag>;
let HasCustomParsing = 1;
- let Documentation = [Undocumented];
+ let Documentation = [TypeTagForDatatypeDocs];
}
// Microsoft-related attributes
let Category = DocCatFunction;
// This function has multiple distinct spellings, and so it requires a custom
// heading to be specified. The most common spelling is sufficient.
- let Heading = "no_sanitize_address";
+ let Heading = "no_sanitize_address (no_address_safety_analysis, gnu::no_address_safety_analysis, gnu::no_sanitize_address)";
let Content = [{
Use ``__attribute__((no_sanitize_address))`` on a function declaration to
specify that address safety instrumentation (e.g. AddressSanitizer) should
to avoid false positives in other places.
}];
}
+
+def TypeSafetyCat : DocumentationCategory<"Type Safety Checking"> {
+ let Content = [{
+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);
+ }];
+}
+
+def ArgumentWithTypeTagDocs : Documentation {
+ let Category = TypeSafetyCat;
+ let Heading = "argument_with_type_tag";
+ let Content = [{
+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) ));
+ }];
+}
+
+def PointerWithTypeTagDocs : Documentation {
+ let Category = TypeSafetyCat;
+ let Heading = "pointer_with_type_tag";
+ let Content = [{
+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) ));
+ }];
+}
+
+def TypeTagForDatatypeDocs : Documentation {
+ let Category = TypeSafetyCat;
+ let Content = [{
+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
+ }];
+}
// Determine the heading to be used for this attribute.
std::string Heading = Doc.Documentation->getValueAsString("Heading");
+ bool CustomHeading = !Heading.empty();
if (Heading.empty()) {
// If there's only one spelling, we can simply use that.
if (Spellings.size() == 1)
// Print out the heading for the attribute. If there are alternate spellings,
// then display those after the heading.
- if (!Names.empty()) {
+ if (!CustomHeading && !Names.empty()) {
Heading += " (";
for (std::vector<std::string>::const_iterator I = Names.begin(),
E = Names.end(); I != E; ++I) {