@@ -8176,3 +8176,71 @@ of ``nonallocating`` by the compiler.
81768176 }];
81778177}
81788178
8179+ def WrapsDocs : Documentation {
8180+ let Category = DocCatField;
8181+ let Content = [{
8182+ This attribute can be used with type or variable declarations to denote that
8183+ arithmetic containing these marked components have defined overflow behavior.
8184+ Specifically, the behavior is defined as being consistent with two's complement
8185+ wrap-around. For the purposes of sanitizers or warnings that concern themselves
8186+ with the definedness of integer arithmetic, they will cease to instrument or
8187+ warn about arithmetic that directly involves a "wrapping" component.
8188+
8189+ For example, ``-fsanitize=signed-integer-overflow`` or ``-Winteger-overflow``
8190+ will not warn about suspicious overflowing arithmetic -- assuming correct usage
8191+ of the wraps attribute.
8192+
8193+ This example shows some basic usage of ``__attribute__((wraps))`` on a type
8194+ definition when building with ``-fsanitize=signed-integer-overflow``
8195+
8196+ .. code-block:: c
8197+
8198+ typedef int __attribute__((wraps)) wrapping_int;
8199+
8200+ void foo() {
8201+ wrapping_int a = INT_MAX;
8202+ ++a; // no sanitizer warning
8203+ }
8204+
8205+ int main() { foo(); }
8206+
8207+ In the following example, we use ``__attribute__((wraps))`` on a variable to
8208+ disable overflow instrumentation for arithmetic expressions it appears in. We
8209+ do so with a popular overflow-checking pattern which we might not want to trip
8210+ sanitizers (like ``-fsanitize=unsigned-integer-overflow``).
8211+
8212+ .. code-block:: c
8213+
8214+ void foo(int offset) {
8215+ unsigned int A __attribute__((wraps)) = UINT_MAX;
8216+
8217+ // check for overflow using a common pattern, however we may accidentally
8218+ // perform a real overflow thus triggering sanitizers to step in. Since "A"
8219+ // is "wrapping", we can avoid sanitizer warnings.
8220+ if (A + offset < A) {
8221+ // handle overflow manually
8222+ // ...
8223+ return;
8224+ }
8225+
8226+ // now, handle non-overflow case ...
8227+ }
8228+
8229+ The above example demonstrates some of the power and elegance this attribute
8230+ provides. We can use code patterns we are already familiar with (like ``if (x +
8231+ y < x)``) while gaining control over the overflow behavior on a case-by-case
8232+ basis.
8233+
8234+ When combined with ``-fwrapv``, this attribute can still be applied as normal
8235+ but has no function apart from annotating types and variables for readers. This
8236+ is because ``-fwrapv`` defines all arithmetic as being "wrapping", rendering
8237+ this attribute's efforts redundant.
8238+
8239+ When using this attribute without ``-fwrapv`` and without any sanitizers, it
8240+ still has an impact on the definedness of arithmetic expressions containing
8241+ wrapping components. Since the behavior of said expressions is now technically
8242+ defined, the compiler will forgo some eager optimizations that are used on
8243+ expressions containing UB.
8244+ }];
8245+ }
8246+
0 commit comments