[clang] [Clang] add wraps and no_wraps attributes (PR #115094)

Justin Stitt via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 12 17:08:41 PST 2024


================
@@ -8710,3 +8710,103 @@ Declares that a function potentially allocates heap memory, and prevents any pot
 of ``nonallocating`` by the compiler.
   }];
 }
+
+def WrapsDocs : Documentation {
+  let Category = DocCatField;
+  let Content = [{
+The ``wraps`` attribute can be used with type or variable declarations to
+denote that arithmetic containing attributed types or variables have defined
+overflow behavior. Specifically, the behavior is defined as being consistent
+with two's complement wrap-around. For the purposes of sanitizers or warnings
+that concern themselves with the definedness of integer arithmetic, they will
+cease to instrument or warn about arithmetic that directly involves operands
+attributed with the ``wraps`` attribute.
+
+The ``signed-integer-overflow``, ``unsigned-integer-overflow``,
+``implicit-signed-integer-truncation`` and the
+``implicit-unsigned-integer-truncation`` sanitizers will not instrument
+arithmetic containing any operands attributed by ``wraps``. Similarly, the
+``-Winteger-overflow`` warning is disabled for these instances.
+
+The following example shows how one may disable ``signed-integer-overflow``
+sanitizer instrumentation using ``__attribute__((wraps))`` on a type definition
+when building with ``-fsanitize=signed-integer-overflow``:
+
+.. code-block:: c
+
+  typedef int __attribute__((wraps)) wrapping_int;
+
+  void foo(void) {
+    wrapping_int A = INT_MAX;
+    ++A; // no sanitizer instrumentation
+  }
+
+``wraps`` may also be used with function parameters or declarations of
+variables as well as members of structures. Using ``wraps`` on non-integer
+types will result in a ``-Wuseless-wraps-attribute`` warning. One may disable
+this warning with ``-Wno-useless-wraps-attribute``.
+
+``wraps`` persists through implicit type promotions and will be applied to the
+result type of arithmetic expressions containing a wrapping operand.
+``-Wimplicitly-discarded-wraps-attribute`` warnings can be caused in situations
+where the ``wraps`` attribute cannot persist through implicit type conversions.
+Disable this with ``-Wno-implicitly-discarded-wraps-attribute``.
+}];
+}
+
+def NoWrapsDocs : Documentation {
+  let Category = DocCatField;
+  let Content = [{
+The ``no_wraps`` attribute can be used to annotate types or variables as
+non-wrapping. This may serve as a helpful annotation to readers of code that
+particular arithmetic expressions involving these types or variables are not
+meant to wrap-around.
+
+When overflow or truncation sanitizer instrumentation is modified at the
+type-level through `SSCLs
+<https://clang.llvm.org/docs/SanitizerSpecialCaseList.html>`_, ``no_wraps`` or
+``wraps`` may be used to override sanitizer behavior.
+
+For example, one may specify an ignorelist (with ``-fsanitize-ignorelist=``) to
+disable the ``signed-integer-overflow`` sanitizer for all types:
+
+.. code-block:: text
+
+  [signed-integer-overflow]
+  type:*
+
+``no_wraps`` can override the behavior provided by the ignorelist to
----------------
JustinStitt wrote:

> 1. Roll-out with over-suppression: ignore list and no_sanitizer attribute.

The current plan for the Kernel is ignoring all types and then using `no_wraps` or `sanitize` (the name of the thing doesn't matter). This helps towards (2)

> 2. If Linux is able to keep up with those checks, maybe reduce suppression scope with available tools.

We will be able to keep up with the checks because we will iteratively expand the scope of `no_wraps` to more types in accordance with what our overflow-fixing bandwidth is.

> 3. Then you may want to go further and need no_wrap/sanitize attribute. But I suspect ROI from step 3 will be so low, that it's not going to happen.

Integer overflow (the unexpected kind) cause a lot of bugs and are an entire attack surface of their own. If we can provide more tools to developers such that enabling sanitizers makes more sense and causes less headaches (false-positives) then I see the ROI being potentially high.

This is what `wraps` or `no_wraps` does. It will help codebases better handle wrapping arithmetic and suddenly it becomes less _magic_ and more _safe_



https://github.com/llvm/llvm-project/pull/115094


More information about the cfe-commits mailing list