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