@@ -8106,3 +8106,72 @@ Attribute used by `clspv`_ (OpenCL-C to Vulkan SPIR-V compiler) to identify func
81068106.. _`libclc`: https://libclc.llvm.org
81078107}];
81088108}
8109+
8110+ def WrapsDocs : Documentation {
8111+ let Category = DocCatField;
8112+ let Content = [{
8113+ This attribute can be used with type or variable declarations to denote that
8114+ arithmetic containing these marked components have defined overflow behavior.
8115+ Specifically, the behavior is defined as being consistent with two's complement
8116+ wrap-around. For the purposes of sanitizers or warnings that concern themselves
8117+ with the definedness of integer arithmetic, they will cease to instrument or
8118+ warn about arithmetic that directly involves a "wrapping" component.
8119+
8120+ For example, ``-fsanitize=signed-integer-overflow`` or ``-Winteger-overflow``
8121+ will not warn about suspicious overflowing arithmetic -- assuming correct usage
8122+ of the wraps attribute.
8123+
8124+ This example shows some basic usage of ``__attribute__((wraps))`` on a type
8125+ definition when building with ``-fsanitize=signed-integer-overflow``
8126+
8127+ .. code-block:: c
8128+
8129+ typedef int __attribute__((wraps)) wrapping_int;
8130+
8131+ void foo() {
8132+ wrapping_int a = INT_MAX;
8133+ ++a; // no sanitizer warning
8134+ }
8135+
8136+ int main() { foo(); }
8137+
8138+ In the following example, we use ``__attribute__((wraps))`` on a variable to
8139+ disable overflow instrumentation for arithmetic expressions it appears in. We
8140+ do so with a popular overflow-checking pattern which we might not want to trip
8141+ sanitizers (like ``-fsanitize=unsigned-integer-overflow``).
8142+
8143+ .. code-block:: c
8144+
8145+ void foo(int offset) {
8146+ unsigned int A __attribute__((wraps)) = UINT_MAX;
8147+
8148+ // to check for overflow using this pattern, we may perform a real overflow
8149+ // thus triggering sanitizers to step in. Since A is "wrapping", we can be
8150+ // sure there are no sanitizer warnings.
8151+ if (A + offset < A) {
8152+ // handle overflow manually
8153+ // ...
8154+ return;
8155+ }
8156+
8157+ // now, handle non-overflow case ...
8158+ }
8159+
8160+ The above example demonstrates some of the power and elegance this attribute
8161+ provides. We can use code patterns we are already familiar with (like ``if (x +
8162+ y < x)``) while gaining control over the overflow behavior on a case-by-case
8163+ basis.
8164+
8165+ When combined with ``-fwrapv``, this attribute can still be applied as normal
8166+ but has no function apart from annotating types and variables for readers. This
8167+ is because ``-fwrapv`` defines all arithmetic as being "wrapping", rending this
8168+ attribute's efforts redundant.
8169+
8170+ When using this attribute without ``-fwrapv`` and without any sanitizers, it
8171+ still has an impact on the definedness of arithmetic expressions containing
8172+ wrapping components. Since the behavior of said expressions is now technically
8173+ defined, the compiler will forgo some eager optimizations that are used on
8174+ expressions containing UB.
8175+ }];
8176+ }
8177+
0 commit comments