================ @@ -0,0 +1,503 @@ +======================== +Function Effect Analysis +======================== + +Introduction +============ + +Clang Function Effect Analysis is a C++ language extension which can warn about "unsafe" +constructs. The feature is currently tailored for the Performance Constraint attributes, +``nonblocking`` and ``nonallocating``; functions with these attributes are verified as not +containing any language constructs or calls to other functions which violate the constraint. +(See :doc:`AttributeReference`.) + + +The ``nonblocking`` and ``nonallocating`` attributes +==================================================== + +Attribute syntax +---------------- + +The ``nonblocking`` and ``nonallocating`` attributes apply to function types, allowing them to be +attached to functions, blocks, function pointers, lambdas, and member functions. + +.. code-block:: c++ + + // Functions + void nonblockingFunction() [[clang::nonblocking]]; + void nonallocatingFunction() [[clang::nonallocating]]; + + // Function pointers + void (*nonblockingFunctionPtr)() [[clang::nonblocking]]; + + // Typedefs, type aliases. + typedef void (*NBFunctionPtrTypedef)() [[clang::nonblocking]]; + using NBFunctionPtrTypeAlias_gnu = __attribute__((nonblocking)) void (*)(); + using NBFunctionPtrTypeAlias_std = void (*)() [[clang::nonblocking]]; + + // C++ methods + struct Struct { + void NBMethod() [[clang::nonblocking]]; + }; + + // C++ lambdas + auto nbLambda = []() [[clang::nonblocking]] {}; + + // Blocks + void (^nbBlock)() = ^() [[clang::nonblocking]] {}; + +The attribute applies only to the function itself. In particular, it does not apply to any nested +functions or declarations, such as blocks, lambdas, and local classes. + +This document uses the C++/C23 syntax ``[[clang::nonblocking]]``, since it parallels the placement +of the ``noexcept`` specifier, and the attributes have other similarities to ``noexcept``. The GNU +``__attribute__((nonblocking))`` syntax is also supported. Note that it requires a different +placement on a C++ type alias. + +Like ``noexcept``, ``nonblocking`` and ``nonallocating`` have an optional argument, a compile-time +constant boolean expression. By default, the argument is true, so ``[[clang::nonblocking(true)]]`` +is equivalent to ``[[clang::nonblocking]]``, and declares the function type as never locking. + + +Attribute semantics +------------------- + +Together with ``noexcept``, the ``nonallocating`` and ``nonblocking`` attributes define an ordered +series of performance constraints. From weakest to strongest: + +- ``noexcept`` (as per the C++ standard): The function type will never throw an exception. +- ``nonallocating``: The function type will never allocate memory on the heap, and never throw an + exception. +- ``nonblocking``: The function type will never block on a lock, never allocate memory on the heap, + and never throw an exception. + +``nonblocking`` includes the ``nonallocating`` guarantee. + +``nonblocking`` and ``nonallocating`` include the ``noexcept`` guarantee, but the presence of either +attribute does not implicitly specify ``noexcept``. (It would be inappropriate for a Clang +attribute, ignored by non-Clang compilers, to imply a standard language feature.) + +``nonblocking(true)`` and ``nonallocating(true)`` apply to function *types*, and by extension, to +function-like declarations. When applied to a declaration with a body, the compiler verifies the +function, as described in the section "Analysis and warnings", below. Functions without an explicit +performance constraint are not verified. + +``nonblocking(false)`` and ``nonallocating(false)`` are synonyms for the attributes ``blocking`` and +``allocating``. They can be used on a function-like declaration to explicitly disable any potential +inference of ``nonblocking`` or ``nonallocating`` during verification. (Inference is described later +in this document). ``nonblocking(false)`` and ``nonallocating(false)`` are legal, but superfluous +when applied to a function *type*. ``float (int) [[nonblocking(false)]]`` and ``float (int)`` are +identical types. + +For all functions with no explicit performance constraint, the worst is assumed, that the function +allocates memory and potentially blocks, unless it can be inferred otherwise, as described in the ---------------- dougsonos wrote:
(Though, I am in the middle of incorporating this round of feedback + fixing whatever else looks wrong...) https://github.com/llvm/llvm-project/pull/109855 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits