@@ -8526,3 +8526,103 @@ Declares that a function potentially allocates heap memory, and prevents any pot
85268526of ``nonallocating`` by the compiler.
85278527 }];
85288528}
8529+
8530+ def WrapsDocs : Documentation {
8531+ let Category = DocCatField;
8532+ let Content = [{
8533+ The ``wraps`` attribute can be used with type or variable declarations to
8534+ denote that arithmetic containing attributed types or variables have defined
8535+ overflow behavior. Specifically, the behavior is defined as being consistent
8536+ with two's complement wrap-around. For the purposes of sanitizers or warnings
8537+ that concern themselves with the definedness of integer arithmetic, they will
8538+ cease to instrument or warn about arithmetic that directly involves operands
8539+ attributed with the ``wraps`` attribute.
8540+
8541+ The ``signed-integer-overflow``, ``unsigned-integer-overflow``,
8542+ ``implicit-signed-integer-truncation`` and the
8543+ ``implicit-unsigned-integer-truncation`` sanitizers will not instrument
8544+ arithmetic containing any operands attributed by ``wraps``. Similarly, the
8545+ ``-Winteger-overflow`` warning is disabled for these instances.
8546+
8547+ The following example shows how one may disable ``signed-integer-overflow``
8548+ sanitizer instrumentation using ``__attribute__((wraps))`` on a type definition
8549+ when building with ``-fsanitize=signed-integer-overflow``:
8550+
8551+ .. code-block:: c
8552+
8553+ typedef int __attribute__((wraps)) wrapping_int;
8554+
8555+ void foo(void) {
8556+ wrapping_int A = INT_MAX;
8557+ ++A; // no sanitizer instrumentation
8558+ }
8559+
8560+ ``wraps`` may also be used with function parameters or declarations of
8561+ variables as well as members of structures. Using ``wraps`` on non-integer
8562+ types will result in a `-Wuseless-wraps-attribute`. One may disable this
8563+ warning with ``-Wno-useless-wraps-attribute``.
8564+
8565+ ``wraps`` persists through implicit type promotions and will be applied to the
8566+ result type of arithmetic expressions containing a wrapping operand.
8567+ ``-Wimplicitly-discarded-wraps-attribute`` warnings can be caused in situations
8568+ where the ``wraps`` attribute cannot persist through implicit type conversions.
8569+ Disable this with ``-Wno-implicitly-discarded-wraps-attribute``.
8570+ }];
8571+ }
8572+
8573+ def NoWrapsDocs : Documentation {
8574+ let Category = DocCatField;
8575+ let Content = [{
8576+ The ``no_wraps`` attribute can be used to annotate types or variables as
8577+ non-wrapping. This may serve as a helpful annotation to readers of code that
8578+ particular arithmetic expressions involving these types or variables are not
8579+ meant to wrap-around.
8580+
8581+ When overflow or truncation sanitizer instrumentation is modified at the
8582+ type-level through `SSCLs
8583+ <https://clang.llvm.org/docs/SanitizerSpecialCaseList.html>`_, ``no_wraps`` or
8584+ ``wraps`` may be used to override sanitizer behavior.
8585+
8586+ For example, one may specify an ignorelist (with ``-fsanitize-ignorelist=``) to
8587+ disable the ``signed-integer-overflow`` sanitizer for all types:
8588+
8589+ .. code-block:: text
8590+
8591+ [signed-integer-overflow]
8592+ type:*
8593+
8594+ ``no_wraps`` can override the behavior provided by the ignorelist to
8595+ effectively re-enable instrumentation for specific types or variables.
8596+
8597+ .. code-block:: c
8598+
8599+ typedef int __attribute__((no_wraps)) non_wrapping_int;
8600+
8601+ void foo(non_wrapping_int A, int B) {
8602+ ++A; // will be instrumented if built with -fsanitize=signed-integer-overflow
8603+ ++B; // won't be instrumented as it is ignored by the ignorelist
8604+ }
8605+
8606+ Like ``wraps``, ``no_wraps`` persists through implicit type promotions and will
8607+ be automatically applied to the result type of arithmetic expressions
8608+ containing a wrapping operand.
8609+
8610+ If a type or variable is attributed by both ``wraps`` and ``no_wraps``, then
8611+ ``no_wraps`` takes precedence -- regardless of the order of attribution.
8612+
8613+ Note that ``no_wraps`` makes no guarantees about the definedness of arithmetic
8614+ overflow. Instead, use ``-fwrapv`` or ``-fno-strict-overflow``.
8615+
8616+ Like ``wraps``, ``no_wraps`` may also be used with function parameters or
8617+ declarations of variables as well as members of structures. Using ``wraps`` on
8618+ non-integer types will result in a `-Wuseless-wraps-attribute`. One may disable
8619+ this warning with ``-Wno-useless-wraps-attribute``.
8620+
8621+ ``no_wraps`` also persists through implicit type promotions and will be applied
8622+ to the result type of arithmetic expressions containing a wrapping operand.
8623+ ``-Wimplicitly-discarded-wraps-attribute`` warnings can be caused in situations
8624+ where the ``wraps`` attribute cannot persist through implicit type conversions.
8625+ Disable this with ``-Wno-implicitly-discarded-wraps-attribute``.
8626+ }];
8627+ }
8628+
0 commit comments