[TargetVersion] Only enable on RISC-V and AArch64 (#115991)
[llvm-project.git] / clang / docs / FunctionEffectAnalysis.rst
blob3f2c4db7bad0cb7a68ad1ae62a05a9417412042d
1 ========================
2 Function Effect Analysis
3 ========================
5 .. contents::
6   :depth: 3
7   :local:
10 Introduction
11 ============
13 Clang Function Effect Analysis is a language extension which can warn about "unsafe"
14 constructs. The feature is currently tailored for the Performance Constraint attributes
15 ``nonblocking`` and ``nonallocating``; functions with these attributes are verified as not
16 containing any language constructs or calls to other functions which violate the constraint.
17 (See :doc:`AttributeReference`.)
20 The ``nonblocking`` and ``nonallocating`` attributes
21 ====================================================
23 Attribute syntax
24 ----------------
26 The ``nonblocking`` and ``nonallocating`` attributes apply to function types, allowing them to be
27 attached to functions, blocks, function pointers, lambdas, and member functions.
29 .. code-block:: c++
31   // Functions
32   void nonblockingFunction() [[clang::nonblocking]];
33   void nonallocatingFunction() [[clang::nonallocating]];
35   // Function pointers
36   void (*nonblockingFunctionPtr)() [[clang::nonblocking]];
38   // Typedefs, type aliases.
39   typedef void (*NBFunctionPtrTypedef)() [[clang::nonblocking]];
40   using NBFunctionPtrTypeAlias_gnu = __attribute__((nonblocking)) void (*)();
41   using NBFunctionPtrTypeAlias_std = void (*)() [[clang::nonblocking]];
43   // C++ methods
44   struct Struct {
45     void NBMethod() [[clang::nonblocking]];
46   };
48   // C++ lambdas
49   auto nbLambda = []() [[clang::nonblocking]] {};
51   // Blocks
52   void (^nbBlock)() = ^() [[clang::nonblocking]] {};
54 The attribute applies only to the function itself. In particular, it does not apply to any nested
55 functions or declarations, such as blocks, lambdas, and local classes.
57 This document uses the C++/C23 syntax ``[[clang::nonblocking]]``, since it parallels the placement
58 of the ``noexcept`` specifier, and the attributes have other similarities to ``noexcept``. The GNU
59 ``__attribute__((nonblocking))`` syntax is also supported. Note that it requires a different
60 placement on a C++ type alias.
62 Like ``noexcept``, ``nonblocking`` and ``nonallocating`` have an optional argument, a compile-time
63 constant boolean expression. By default, the argument is ``true``, so ``[[clang::nonblocking]]``
64 is equivalent to ``[[clang::nonblocking(true)]]``, and declares the function type as never blocking.
67 Attribute semantics
68 -------------------
70 Together with ``noexcept``, the ``nonallocating`` and ``nonblocking`` attributes define an ordered
71 series of performance constraints. From weakest to strongest:
73 - ``noexcept`` (as per the C++ standard): The function type will never throw an exception.
74 - ``nonallocating``: The function type will never allocate memory on the heap or throw an
75   exception.
76 - ``nonblocking``: The function type will never block on a lock, allocate memory on the heap,
77   or throw an exception.
79 ``nonblocking`` includes the ``nonallocating`` guarantee.
81 While ``nonblocking`` and ``nonallocating`` are conceptually a superset of ``noexcept``, neither
82 attribute implicitly specifies ``noexcept``. Further, ``noexcept`` has a specified runtime behavior of
83 aborting if an exception is thrown, while the ``nonallocating`` and ``nonblocking`` attributes are
84 mainly for compile-time analysis and have no runtime behavior, except in code built
85 with Clang's :doc:`RealtimeSanitizer`. Nonetheless, Clang emits a
86 warning if, in C++, a function is declared ``nonblocking`` or ``nonallocating`` without
87 ``noexcept``. This diagnostic is controlled by ``-Wperf-constraint-implies-noexcept``.
89 ``nonblocking(true)`` and ``nonallocating(true)`` apply to function *types*, and by extension, to
90 function-like declarations. When applied to a declaration with a body, the compiler verifies the
91 function, as described in the section "Analysis and warnings", below.
93 ``blocking`` and ``allocating`` are synonyms for ``nonblocking(false)`` and
94 ``nonallocating(false)``, respectively. They can be used on a function-like declaration to
95 explicitly disable any potential inference of ``nonblocking`` or ``nonallocating`` during
96 verification. (Inference is described later in this document). ``nonblocking(false)`` and
97 ``nonallocating(false)`` are legal, but superfluous  when applied to a function *type*
98 that is not part of a declarator: ``float (int) [[nonblocking(false)]]`` and
99 ``float (int)`` are identical types.
101 For functions with no explicit performance constraint, the worst is assumed: the function
102 allocates memory and potentially blocks, unless it can be inferred otherwise. This is detailed in the
103 discussion of verification.
105 The following example describes the meanings of all permutations of the two attributes and arguments:
107 .. code-block:: c++
109   void nb1_na1() [[clang::nonblocking(true)]] [[clang::nonallocating(true)]];
110   // Valid; nonallocating(true) is superfluous but doesn't contradict the guarantee.
112   void nb1_na0() [[clang::nonblocking(true)]] [[clang::nonallocating(false)]];
113   // error: 'allocating' and 'nonblocking' attributes are not compatible
115   void nb0_na1() [[clang::nonblocking(false)]] [[clang::nonallocating(true)]];
116   // Valid; the function does not allocate memory, but may lock for other reasons.
118   void nb0_na0() [[clang::nonblocking(false)]] [[clang::nonallocating(false)]];
119   // Valid.
122 Type conversions
123 ----------------
125 A performance constraint can be removed or weakened via an implicit conversion. An attempt to add
126 or strengthen a performance constraint is unsafe and results in a warning. The rules for this
127 are comparable to that for ``noexcept`` in C++17 and later.
129 .. code-block:: c++
131   void unannotated();
132   void nonblocking() [[clang::nonblocking]];
133   void nonallocating() [[clang::nonallocating]];
135   void example()
136   {
137     // It's fine to remove a performance constraint.
138     void (*fp_plain)();
139     fp_plain = unannotated;
140     fp_plain = nonblocking;
141     fp_plain = nonallocating;
143     // Adding/spoofing nonblocking is unsafe.
144     void (*fp_nonblocking)() [[clang::nonblocking]];
145     fp_nonblocking = nullptr;
146     fp_nonblocking = nonblocking;
147     fp_nonblocking = unannotated;
148     // ^ warning: attribute 'nonblocking' should not be added via type conversion
149     fp_nonblocking = nonallocating;
150     // ^ warning: attribute 'nonblocking' should not be added via type conversion
152     // Adding/spoofing nonallocating is unsafe.
153     void (*fp_nonallocating)() [[clang::nonallocating]];
154     fp_nonallocating = nullptr;
155     fp_nonallocating = nonallocating;
156     fp_nonallocating = nonblocking; // no warning because nonblocking includes nonallocating
157     fp_nonallocating = unannotated;
158     // ^ warning: attribute 'nonallocating' should not be added via type conversion
159   }
161 Virtual methods
162 ---------------
164 In C++, when a virtual method has a performance constraint, overriding methods in
165 subclasses inherit the constraint.
167 .. code-block:: c++
169   struct Base {
170     virtual void unsafe();
171     virtual void safe() noexcept [[clang::nonblocking]];
172   };
174   struct Derived : public Base {
175     void unsafe() [[clang::nonblocking]] override;
176     // It's okay for an overridden method to be more constrained
178     void safe() noexcept override;
179     // This method is implicitly declared `nonblocking`, inherited from Base.
180   };
182 Redeclarations, overloads, and name mangling
183 --------------------------------------------
185 The ``nonblocking`` and ``nonallocating`` attributes, like ``noexcept``, do not factor into
186 argument-dependent lookup and overloaded functions/methods.
188 First, consider that ``noexcept`` is integral to a function's type:
190 .. code-block:: c++
192   void f1(int);
193   void f1(int) noexcept;
194   // error: exception specification in declaration does not match previous
195   //   declaration
197 Unlike ``noexcept``, a redeclaration of ``f2`` with an added or stronger performance constraint is
198 legal and propagates the attribute to the previous declaration:
200 .. code-block:: c++
202   int f2();
203   int f2() [[clang::nonblocking]]; // redeclaration with stronger constraint is OK.
205 This greatly eases adoption by making it possible to annotate functions in external libraries
206 without modifying library headers.
208 A redeclaration with a removed or weaker performance constraint produces a warning, paralleling
209 the behavior of ``noexcept``:
211 .. code-block:: c++
213   int f2() { return 42; }
214   // warning: attribute 'nonblocking' on function does not match previous declaration
216 In C++14, the following two declarations of `f3` are identical (a single function). In C++17 they
217 are separate overloads:
219 .. code-block:: c++
221   void f3(void (*)());
222   void f3(void (*)() noexcept);
224 Similarly, the following two declarations of `f4` are separate overloads. This pattern may pose
225 difficulties due to ambiguity:
227 .. code-block:: c++
229   void f4(void (*)());
230   void f4(void (*)() [[clang::nonblocking]]);
232 The attributes have no effect on the mangling of function and method names.
234 Objective-C
235 -----------
237 The attributes are currently unsupported on Objective-C methods.
239 Analysis and warnings
240 =====================
242 Constraints
243 -----------
245 Functions declared ``nonallocating`` or ``nonblocking``, when defined, are verified according to the
246 following rules. Such functions:
248 1. May not allocate or deallocate memory on the heap. The analysis follows the calls to
249    ``operator new`` and ``operator delete`` generated by the ``new`` and ``delete`` keywords, and
250    treats them like any other function call. The global ``operator new`` and ``operator delete``
251    aren't declared ``nonblocking`` or ``nonallocating`` and so they are considered unsafe. (This
252    is correct because most memory allocators are not lock-free. Note that the placement form of
253    ``operator new`` is implemented inline in libc++'s ``<new>`` header, and is verifiably
254    ``nonblocking``, since it merely casts the supplied pointer to the result type.)
256 2. May not throw or catch exceptions. To throw, the compiler must allocate the exception on the
257    heap. (Also, many subclasses of ``std::exception`` allocate a string). Exceptions are
258    deallocated when caught.
260 3. May not make any indirect function call, via a virtual method, function pointer, or
261    pointer-to-member function, unless the target is explicitly declared with the same
262    ``nonblocking`` or ``nonallocating`` attribute (or stronger).
264 4. May not make direct calls to any other function, with the following exceptions:
266   a. The callee is also explicitly declared with the same ``nonblocking`` or ``nonallocating``
267      attribute (or stronger).
268   b. The callee is defined in the same translation unit as the caller, does not have the ``false``
269      form of the required attribute, and can be verified to have the same attribute or stronger,
270      according to these same rules.
271   c. The callee is a built-in function that is known not to block or allocate.
272   d. The callee is declared ``noreturn`` and, if compiling C++, the callee is also declared
273      ``noexcept``. This special case excludes functions such as ``abort()`` and ``std::terminate()``
274      from the analysis. (The reason for requiring ``noexcept`` in C++ is that a function declared
275      ``noreturn`` could be a wrapper for ``throw``.)
277 5. May not invoke or access an Objective-C method or property, since ``objc_msgSend()`` calls into
278    the Objective-C runtime, which may allocate memory or otherwise block.
280 6. May not access thread-local variables. Typically, thread-local variables are allocated on the
281    heap when first accessed.
283 Functions declared ``nonblocking`` have an additional constraint:
285 7. May not declare static local variables (e.g. Meyers singletons). The compiler generates a lock
286    protecting the initialization of the variable.
288 Violations of any of these rules result in warnings, in the ``-Wfunction-effects`` category:
290 .. code-block:: c++
292   void notInline();
294   void example() [[clang::nonblocking]]
295   {
296     auto* x = new int;
297     // warning: function with 'nonblocking' attribute must not allocate or deallocate
298     //   memory
300     if (x == nullptr) {
301       static Logger* logger = createLogger();
302       // warning: function with 'nonblocking' attribute must not have static local variables
304       throw std::runtime_warning{ "null" };
305       // warning: 'nonblocking" function 'example' must not throw exceptions
306     }
307     notInline();
308     // warning: 'function with 'nonblocking' attribute must not call non-'nonblocking' function
309     //   'notInline'
310     // note (on notInline()): declaration cannot be inferred 'nonblocking' because it has no
311     //   definition in this translation unit
312   }
314 Inferring ``nonblocking`` or ``nonallocating``
315 ----------------------------------------------
317 In the absence of a ``nonblocking`` or ``nonallocating`` attribute (whether ``true`` or ``false``),
318 a function that is called from a performance-constrained function may be analyzed to
319 infer whether it has a desired attribute. This analysis happens when the function is not a virtual
320 method, and it has a visible definition within the current translation unit (i.e. its body can be
321 traversed).
323 .. code-block:: c++
325   void notInline();
326   int implicitlySafe() { return 42; }
327   void implicitlyUnsafe() { notInline(); }
329   void example() [[clang::nonblocking]]
330   {
331     int x = implicitlySafe(); // OK
332     implicitlyUnsafe();
333     // warning: function with 'nonblocking' attribute must not call non-'nonblocking' function
334     //   'implicitlyUnsafe'
335     // note (on implicitlyUnsafe): function cannot be inferred 'nonblocking' because it calls
336     //   non-'nonblocking' function 'notInline'
337     // note (on notInline()): declaration cannot be inferred 'nonblocking' because it has no
338     //   definition in this translation unit
339   }
341 Lambdas and blocks
342 ------------------
344 As mentioned earlier, the performance constraint attributes apply only to a single function and not
345 to any code nested inside it, including blocks, lambdas, and local classes. It is possible for a
346 nonblocking function to schedule the execution of a blocking lambda on another thread. Similarly, a
347 blocking function may create a ``nonblocking`` lambda for use in a realtime context.
349 Operations which create, destroy, copy, and move lambdas and blocks are analyzed in terms of the
350 underlying function calls. For example, the creation of a lambda with captures generates a function
351 call to an anonymous struct's constructor, passing the captures as parameters.
353 Implicit function calls in the AST
354 ----------------------------------
356 The ``nonblocking`` / ``nonallocating`` analysis occurs at the Sema phase of analysis in Clang.
357 During Sema, there are some constructs which will eventually become function calls, but do not
358 appear as function calls in the AST. For example, ``auto* foo = new Foo;`` becomes a declaration
359 containing a ``CXXNewExpr`` which is understood as a function call to the global ``operator new``
360 (in this example), and a ``CXXConstructExpr``, which, for analysis purposes, is a function call to
361 ``Foo``'s constructor. Most gaps in the analysis would be due to incomplete knowledge of AST
362 constructs which become function calls.
364 Disabling diagnostics
365 ---------------------
367 Function effect diagnostics are controlled by ``-Wfunction-effects``.
369 A construct like this can be used to exempt code from the checks described here:
371 .. code-block:: c++
373   #define NONBLOCKING_UNSAFE(...)                                    \
374     _Pragma("clang diagnostic push")                                 \
375     _Pragma("clang diagnostic ignored \"-Wunknown-warning-option\"") \
376     _Pragma("clang diagnostic ignored \"-Wfunction-effects\"")       \
377     __VA_ARGS__                                                      \
378     _Pragma("clang diagnostic pop")
380 Disabling the diagnostic allows for:
382 - constructs which do block, but which in practice are used in ways to avoid unbounded blocking,
383   e.g. a thread pool with semaphores to coordinate multiple realtime threads;
384 - using libraries which are safe but not yet annotated;
385 - incremental adoption in a large codebase.
387 Adoption
388 ========
390 There are a few common issues that arise when adopting the ``nonblocking`` and ``nonallocating``
391 attributes.
393 C++ exceptions
394 --------------
396 Exceptions pose a challenge to the adoption of the performance constraints. Common library functions
397 which throw exceptions include:
399 +----------------------------------+-----------------------------------------------------------------------+
400 | Method                           | Alternative                                                           |
401 +==================================+=======================================================================+
402 | ``std::vector<T>::at()``         | ``operator[](size_t)``, after verifying that the index is in range.   |
403 +----------------------------------+-----------------------------------------------------------------------+
404 | ``std::optional<T>::value()``    | ``operator*``, after checking ``has_value()`` or ``operator bool()``. |
405 +----------------------------------+-----------------------------------------------------------------------+
406 | ``std::expected<T, E>::value()`` | Same as for ``std::optional<T>::value()``.                            |
407 +----------------------------------+-----------------------------------------------------------------------+
410 ``std::function<R(Args...)>``
411 -----------------------------
413 ``std::function<R(Args...)>`` is generally incompatible with ``nonblocking`` and ``nonallocating``
414 code, because a typical implementation may allocate heap memory in the constructor.
416 Alternatives:
418 - ``std::function_ref`` (available in C++26 or as ``llvm::function_ref``). This is appropriate and
419   optimal when a functor's lifetime does not need to extend past the function that created it.
421 - ``inplace_function`` from WG14. This solves the allocation problem by giving the functor wrapper
422   a fixed size known at compile time and using an inline buffer.
424 While these alternatives both address the heap allocation of ``std::function``, they are still
425 obstacles to ``nonblocking/nonallocating`` verification, for reasons detailed in the next section.
428 Interactions with type-erasure techniques
429 -----------------------------------------
431 ``std::function<R(Args...)>`` illustrates a common C++ type-erasure technique. Using template
432 argument deduction, it decomposes a function type into its return and parameter types. Additional
433 components of the function type, including ``noexcept``, ``nonblocking``, ``nonallocating``, and any
434 other attributes, are discarded.
436 Standard library support for these components of a function type is not immediately forthcoming.
438 Code can work around this limitation in either of two ways:
440 1. Avoid abstractions like ``std::function`` and instead work directly with the original lambda type.
442 2. Create a specialized alternative, e.g. ``nonblocking_function_ref<R(Args...)>`` where all function
443    pointers used in the implementation and its interface are ``nonblocking``.
445 As an example of the first approach, when using a lambda as a *Callable* template parameter, the
446 attribute is preserved:
448 .. code-block:: c++
450   std::sort(vec.begin(), vec.end(),
451     [](const Elem& a, const Elem& b) [[clang::nonblocking]] { return a.mem < b.mem; });
453 Here, the type of the ``Compare`` template parameter is an anonymous class generated from the
454 lambda, with an ``operator()`` method holding the ``nonblocking`` attribute.
456 A complication arises when a *Callable* template parameter, instead of being a lambda or class
457 implementing ``operator()``, is a function pointer:
459 .. code-block:: c++
461   static bool compare_elems(const Elem& a, const Elem& b) [[clang::nonblocking]] {
462     return a.mem < b.mem; };
464   std::sort(vec.begin(), vec.end(), compare_elems);
466 Here, the type of ``compare_elems`` is decomposed to ``bool(const Elem&, const Elem&)``, without
467 ``nonblocking``, when forming the template parameter. This can be solved using the second approach,
468 creating a specialized alternative which explicitly requires the attribute. In this case, it's
469 possible to use a small wrapper to transform the function pointer into a functor:
471 .. code-block:: c++
473   template <typename>
474   class nonblocking_fp;
476   template <typename R, typename... Args>
477   class nonblocking_fp<R(Args...)> {
478   public:
479     using impl_t = R (*)(Args...) [[clang::nonblocking]];
481   private:
482     impl_t mImpl{ nullptr_t };
483   public:
484     nonblocking_fp() = default;
485     nonblocking_fp(impl_t f) : mImpl{ f } {}
487     R operator()(Args... args) const
488     {
489       return mImpl(std::forward<Args>(args)...);
490     }
491   };
493   // deduction guide (like std::function's)
494   template< class R, class... ArgTypes >
495   nonblocking_fp( R(*)(ArgTypes...) ) -> nonblocking_fp<R(ArgTypes...)>;
497   // --
499   // Wrap the function pointer in a functor which preserves ``nonblocking``.
500   std::sort(vec.begin(), vec.end(), nonblocking_fp{ compare_elems });
502 Now, the ``nonblocking`` attribute of ``compare_elems`` is verified when it is converted to a
503 ``nonblocking`` function pointer, as the argument to ``nonblocking_fp``'s constructor. The template
504 parameter is the functor class ``nonblocking_fp``.
507 Static local variables
508 ----------------------
510 Static local variables are often used for lazily-constructed globals (Meyers singletons). Beyond the
511 compiler's use of a lock to ensure thread-safe initialization, it is dangerously easy to
512 inadvertently trigger initialization, involving heap allocation, from a ``nonblocking`` or
513 ``nonallocating`` context.
515 Generally, such singletons need to be replaced by globals, and care must be taken to ensure their
516 initialization before they are used from ``nonblocking`` or ``nonallocating`` contexts.
519 Annotating libraries
520 --------------------
522 It can be surprising that the analysis does not depend on knowledge of any primitives; it simply
523 assumes the worst, that all function calls are unsafe unless explicitly marked as safe or able to be
524 inferred as safe. With ``nonblocking``, this appears to suffice for all but the most primitive of
525 spinlocks.
527 At least for an operating system's C functions, it is possible to define an override header which
528 redeclares safe common functions (e.g. ``pthread_self()``) with the addition of ``nonblocking``.
529 This may help in adopting the feature incrementally.
531 It also helps that many of the functions in the standard C libraries (notably ``<math.h>``)
532 are treated as built-in functions by Clang, which the diagnosis understands to be safe.
534 Much of the C++ standard library consists of inline templated functions which work well with
535 inference. A small number of primitives may need explicit ``nonblocking/nonallocating`` attributes.