@@ -8333,3 +8333,71 @@ of ``nonallocating`` by the compiler.
83338333 }];
83348334}
83358335
8336+ def WrapsDocs : Documentation {
8337+ let Category = DocCatField;
8338+ let Content = [{
8339+ This attribute can be used with type or variable declarations to denote that
8340+ arithmetic containing these marked components have defined overflow behavior.
8341+ Specifically, the behavior is defined as being consistent with two's complement
8342+ wrap-around. For the purposes of sanitizers or warnings that concern themselves
8343+ with the definedness of integer arithmetic, they will cease to instrument or
8344+ warn about arithmetic that directly involves a "wrapping" component.
8345+
8346+ For example, ``-fsanitize=signed-integer-overflow`` or ``-Winteger-overflow``
8347+ will not warn about suspicious overflowing arithmetic -- assuming correct usage
8348+ of the wraps attribute.
8349+
8350+ This example shows some basic usage of ``__attribute__((wraps))`` on a type
8351+ definition when building with ``-fsanitize=signed-integer-overflow``
8352+
8353+ .. code-block:: c
8354+
8355+ typedef int __attribute__((wraps)) wrapping_int;
8356+
8357+ void foo() {
8358+ wrapping_int a = INT_MAX;
8359+ ++a; // no sanitizer warning
8360+ }
8361+
8362+ int main() { foo(); }
8363+
8364+ In the following example, we use ``__attribute__((wraps))`` on a variable to
8365+ disable overflow instrumentation for arithmetic expressions it appears in. We
8366+ do so with a popular overflow-checking pattern which we might not want to trip
8367+ sanitizers (like ``-fsanitize=unsigned-integer-overflow``).
8368+
8369+ .. code-block:: c
8370+
8371+ void foo(int offset) {
8372+ unsigned int A __attribute__((wraps)) = UINT_MAX;
8373+
8374+ // check for overflow using a common pattern, however we may accidentally
8375+ // perform a real overflow thus triggering sanitizers to step in. Since "A"
8376+ // is "wrapping", we can avoid sanitizer warnings.
8377+ if (A + offset < A) {
8378+ // handle overflow manually
8379+ // ...
8380+ return;
8381+ }
8382+
8383+ // now, handle non-overflow case ...
8384+ }
8385+
8386+ The above example demonstrates some of the power and elegance this attribute
8387+ provides. We can use code patterns we are already familiar with (like ``if (x +
8388+ y < x)``) while gaining control over the overflow behavior on a case-by-case
8389+ basis.
8390+
8391+ When combined with ``-fwrapv``, this attribute can still be applied as normal
8392+ but has no function apart from annotating types and variables for readers. This
8393+ is because ``-fwrapv`` defines all arithmetic as being "wrapping", rendering
8394+ this attribute's efforts redundant.
8395+
8396+ When using this attribute without ``-fwrapv`` and without any sanitizers, it
8397+ still has an impact on the definedness of arithmetic expressions containing
8398+ wrapping components. Since the behavior of said expressions is now technically
8399+ defined, the compiler will forgo some eager optimizations that are used on
8400+ expressions containing UB.
8401+ }];
8402+ }
8403+
0 commit comments