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

2024-11-24 Thread Vitaly Buka via cfe-commits

vitalybuka wrote:

> @vitalybuka
> 
> > Would it make sense to support attributes like 
> > `__attribute__((no_sanitize("-undefined")))` ? Seems like better 
> > representation of the fact that we want to undo sanitizer suppression.
> 
> Is there some other precedence for this `-undefined` syntax with attributes?

No.

> 
> I am working on the PR for supporting `__attribute__((no_sanitize()))` for 
> types. Should the opposite of `no_sanitize` be `sanitizable`? I agree that 
> `sanitize` is no good as it suggests it will enable sanitization, not permit 
> it.

sanitizable is LGTM

> 
> Once I have that PR up can compare it to this PR to find the best way forward.



https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-18 Thread Justin Stitt via cfe-commits

JustinStitt wrote:

@vitalybuka 
> Would it make sense to support attributes like 
> `__attribute__((no_sanitize("-undefined")))` ? Seems like better 
> representation of the fact that we want to undo sanitizer suppression.

I am working on the PR for supporting `__attribute__((no_sanitize()))` for 
types. Should the opposite of `no_sanitize` be `sanitizeable`? I agree that 
`sanitize` is no good as it suggests it will enable sanitization, not permit it.

Once I have that PR up can compare it to this PR to find the best way forward.



https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Vitaly Buka via cfe-commits

vitalybuka wrote:

Naming wise I prefer `wrap` -> `no_sanitize("undefined")` already exists but 
does not apply to variables and types

`no_wrap` -> `sanitize("undefined")` does not exist, and a little confusing 
(no_wrap as well). It may look it enabled sanitization.

Would it make sense to support attributes like  
`__attribute__((no_sanitize("-undefined")))` ? Seems like better representation 
of the fact that we want to undo sanitizer suppression. @erichkeane  WDYT


https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Vitaly Buka via cfe-commits

https://github.com/vitalybuka edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Vitaly Buka via cfe-commits


@@ -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
+`_, ``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

vitalybuka wrote:

> 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) on a few types. This helps 
> towards (2.)

I see, you are doing this in opposite way. My intuition it's more complicated 
than needed. But I didn't work on Kernel, maybe there are own specifics. It 
looks like you need to allow all types used in kernel one by one in the end.

We tried allow list like approach in google3. It usually goes slower then 
ignore list approach - sanitizer everything that pass, the rest go in ignore 
list, usually by src: or fun:. Then next stage shrinking ignore list by fixing 
or converting to attribute on functions.

@ramosian-glider  has experience with other sanitizers, maybe you have opinion 
on the approach 
https://github.com/llvm/llvm-project/pull/115094#discussion_r1839130783?

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Justin Stitt via cfe-commits

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

>From b5515eba87ffd96d010952bf18fe4044861df298 Mon Sep 17 00:00:00 2001
From: Justin Stitt 
Date: Tue, 5 Mar 2024 03:14:49 +
Subject: [PATCH 01/15] add wraps, no_wraps attributes

---
 clang/docs/ReleaseNotes.rst   |  20 
 clang/docs/SanitizerSpecialCaseList.rst   |   2 +
 clang/include/clang/AST/Expr.h|   6 ++
 clang/include/clang/AST/Type.h|   3 +
 clang/include/clang/Basic/Attr.td |  15 +++
 clang/include/clang/Basic/AttrDocs.td | 100 ++
 clang/include/clang/Basic/DiagnosticGroups.td |   6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   7 ++
 clang/lib/AST/Expr.cpp|  20 
 clang/lib/AST/ExprConstant.cpp|   4 +-
 clang/lib/AST/Type.cpp|   9 ++
 clang/lib/AST/TypePrinter.cpp |   6 ++
 clang/lib/CodeGen/CGExprScalar.cpp|  48 ++---
 clang/lib/Sema/Sema.cpp   |   3 +
 clang/lib/Sema/SemaChecking.cpp   |  35 +-
 clang/lib/Sema/SemaDecl.cpp   |   2 +-
 clang/lib/Sema/SemaDeclAttr.cpp   |  16 ++-
 clang/lib/Sema/SemaType.cpp   |  25 +
 clang/test/CodeGen/integer-overflow.c |  66 
 clang/test/CodeGen/unsigned-overflow.c|  63 +--
 clang/test/CodeGen/wraps-attribute-scl.test   |  78 ++
 ...a-attribute-supported-attributes-list.test |   2 +
 clang/test/Sema/attr-wraps.c  |  48 +
 23 files changed, 556 insertions(+), 28 deletions(-)
 create mode 100644 clang/test/CodeGen/wraps-attribute-scl.test
 create mode 100644 clang/test/Sema/attr-wraps.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0b0f2053f634ee..fd12e0e8d201d5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -433,6 +433,26 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow behavior for that expression as having
+  two's complement wrap-around. These expressions will not be instrumented by
+  overflow sanitizers nor will they cause integer overflow warnings. They also
+  cannot be optimized away by some eager UB optimizations as the behavior of
+  the arithmetic is no longer "undefined".
+
+  There is also ``__attribute__((no_wraps))`` which can be added to types or
+  variable declarations. Types or variables with this attribute may be
+  instrumented by overflow sanitizers, if enabled. Note that this matches the
+  default behavior of integer types. So, in most cases, ``no_wraps`` serves
+  purely as an annotation to readers of code that a type or variable really
+  shouldn't wrap-around. ``__attribute__((no_wraps))`` has the most function
+  when paired with `Sanitizer Special Case Lists (SSCL)
+  `_.
+
+  These attributes are only valid for C, as there are built-in language
+  alternatives for other languages.
+
 Improvements to Clang's diagnostics
 ---
 
diff --git a/clang/docs/SanitizerSpecialCaseList.rst 
b/clang/docs/SanitizerSpecialCaseList.rst
index 5c88c2976e8613..274409f47437c4 100644
--- a/clang/docs/SanitizerSpecialCaseList.rst
+++ b/clang/docs/SanitizerSpecialCaseList.rst
@@ -67,9 +67,11 @@ types specified within an ignorelist.
 int a = 2147483647; // INT_MAX
 ++a;// Normally, an overflow with 
-fsanitize=signed-integer-overflow
   }
+
   $ cat ignorelist.txt
   [signed-integer-overflow]
   type:int
+
   $ clang -fsanitize=signed-integer-overflow 
-fsanitize-ignorelist=ignorelist.txt foo.c ; ./a.out
   # no signed-integer-overflow error
 
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 466c65a9685ad3..4472c941ed5c79 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -4142,6 +4142,12 @@ class BinaryOperator : public Expr {
 return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
   }
 
+  /// Does one of the subexpressions have the wraps attribute?
+  bool hasWrappingOperand(const ASTContext &Ctx) const;
+
+  /// How about the no_wraps attribute?
+  bool hasNonWrappingOperand(const ASTContext &Ctx) const;
+
 protected:
   BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
  QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 8979129017163b..30217408856783 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/includ

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

2024-11-12 Thread Justin Stitt via cfe-commits


@@ -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
+`_, ``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:

@vitalybuka  Look at AOSP for example: 
https://android-review.googlesource.com/c/kernel/common/+/3343205

> Sanitizing signed integer overflow in Linux kernel might be useful to
> spot bugs, however there are cases where overflow is intended, for
> example, `atomic_long_t` type and such cases can't be annotated to not
> trigger UBSAN.

They, and other kernel projects that use sanitizers, really want a wraps or 
wraps-equivalent _thing_.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Justin Stitt via cfe-commits

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

>From b5515eba87ffd96d010952bf18fe4044861df298 Mon Sep 17 00:00:00 2001
From: Justin Stitt 
Date: Tue, 5 Mar 2024 03:14:49 +
Subject: [PATCH 01/14] add wraps, no_wraps attributes

---
 clang/docs/ReleaseNotes.rst   |  20 
 clang/docs/SanitizerSpecialCaseList.rst   |   2 +
 clang/include/clang/AST/Expr.h|   6 ++
 clang/include/clang/AST/Type.h|   3 +
 clang/include/clang/Basic/Attr.td |  15 +++
 clang/include/clang/Basic/AttrDocs.td | 100 ++
 clang/include/clang/Basic/DiagnosticGroups.td |   6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   7 ++
 clang/lib/AST/Expr.cpp|  20 
 clang/lib/AST/ExprConstant.cpp|   4 +-
 clang/lib/AST/Type.cpp|   9 ++
 clang/lib/AST/TypePrinter.cpp |   6 ++
 clang/lib/CodeGen/CGExprScalar.cpp|  48 ++---
 clang/lib/Sema/Sema.cpp   |   3 +
 clang/lib/Sema/SemaChecking.cpp   |  35 +-
 clang/lib/Sema/SemaDecl.cpp   |   2 +-
 clang/lib/Sema/SemaDeclAttr.cpp   |  16 ++-
 clang/lib/Sema/SemaType.cpp   |  25 +
 clang/test/CodeGen/integer-overflow.c |  66 
 clang/test/CodeGen/unsigned-overflow.c|  63 +--
 clang/test/CodeGen/wraps-attribute-scl.test   |  78 ++
 ...a-attribute-supported-attributes-list.test |   2 +
 clang/test/Sema/attr-wraps.c  |  48 +
 23 files changed, 556 insertions(+), 28 deletions(-)
 create mode 100644 clang/test/CodeGen/wraps-attribute-scl.test
 create mode 100644 clang/test/Sema/attr-wraps.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0b0f2053f634ee..fd12e0e8d201d5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -433,6 +433,26 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow behavior for that expression as having
+  two's complement wrap-around. These expressions will not be instrumented by
+  overflow sanitizers nor will they cause integer overflow warnings. They also
+  cannot be optimized away by some eager UB optimizations as the behavior of
+  the arithmetic is no longer "undefined".
+
+  There is also ``__attribute__((no_wraps))`` which can be added to types or
+  variable declarations. Types or variables with this attribute may be
+  instrumented by overflow sanitizers, if enabled. Note that this matches the
+  default behavior of integer types. So, in most cases, ``no_wraps`` serves
+  purely as an annotation to readers of code that a type or variable really
+  shouldn't wrap-around. ``__attribute__((no_wraps))`` has the most function
+  when paired with `Sanitizer Special Case Lists (SSCL)
+  `_.
+
+  These attributes are only valid for C, as there are built-in language
+  alternatives for other languages.
+
 Improvements to Clang's diagnostics
 ---
 
diff --git a/clang/docs/SanitizerSpecialCaseList.rst 
b/clang/docs/SanitizerSpecialCaseList.rst
index 5c88c2976e8613..274409f47437c4 100644
--- a/clang/docs/SanitizerSpecialCaseList.rst
+++ b/clang/docs/SanitizerSpecialCaseList.rst
@@ -67,9 +67,11 @@ types specified within an ignorelist.
 int a = 2147483647; // INT_MAX
 ++a;// Normally, an overflow with 
-fsanitize=signed-integer-overflow
   }
+
   $ cat ignorelist.txt
   [signed-integer-overflow]
   type:int
+
   $ clang -fsanitize=signed-integer-overflow 
-fsanitize-ignorelist=ignorelist.txt foo.c ; ./a.out
   # no signed-integer-overflow error
 
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 466c65a9685ad3..4472c941ed5c79 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -4142,6 +4142,12 @@ class BinaryOperator : public Expr {
 return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
   }
 
+  /// Does one of the subexpressions have the wraps attribute?
+  bool hasWrappingOperand(const ASTContext &Ctx) const;
+
+  /// How about the no_wraps attribute?
+  bool hasNonWrappingOperand(const ASTContext &Ctx) const;
+
 protected:
   BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
  QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 8979129017163b..30217408856783 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/includ

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

2024-11-12 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Justin Stitt via cfe-commits


@@ -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
+`_, ``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
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Justin Stitt via cfe-commits


@@ -4852,6 +4862,10 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, 
Expr *lhs, Expr *rhs,
   if (hasStoredFPFeatures())
 setStoredFPFeatures(FPFeatures);
   setDependence(computeDependence(this));
+  if (hasWrappingOperand(Ctx))

JustinStitt wrote:

As of 
https://github.com/llvm/llvm-project/pull/115094/commits/445f8c7c93484a5476d85e05a289e609e3f38a94,
 only one attribute will persist through to BinaryOperators. Thanks

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Justin Stitt via cfe-commits


@@ -10818,11 +10819,39 @@ static bool IsImplicitBoolFloatConversion(Sema &S, 
Expr *Ex, bool ToBool) {
   FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
 }
 
+/// Check to see if the wraps or no_wraps attribute may have been lost through
+/// a function call. For cases where we are unsure, assume not.
+static bool IsWrapsAttrLost(Sema &S, const CallExpr *TheCall,
+const FunctionDecl *FD, unsigned i) {
+  // We may not have a FunctionDecl if this CallExpr is associated virtual,
+  // templated or overloaded functions.
+  if (!FD)
+return false;
+
+  if (i >= TheCall->getNumArgs() || i >= FD->getNumParams())
+return false;
+
+  const QualType ProvidedArgTy = TheCall->getArg(i)->getType();
+  const QualType PrototypedArgTy = FD->getParamDecl(i)->getType();
+
+  return (ProvidedArgTy.hasWrapsAttr() && !PrototypedArgTy.hasWrapsAttr()) ||
+ (ProvidedArgTy.hasNoWrapsAttr() && !PrototypedArgTy.hasNoWrapsAttr());
+}
+
 static void CheckImplicitArgumentConversions(Sema &S, CallExpr *TheCall,
  SourceLocation CC) {
   unsigned NumArgs = TheCall->getNumArgs();
+  const FunctionDecl *FD = TheCall->getDirectCallee();
+
   for (unsigned i = 0; i < NumArgs; ++i) {
 Expr *CurrA = TheCall->getArg(i);
+
+if (IsWrapsAttrLost(S, TheCall, FD, i))

JustinStitt wrote:


> This is looking an AWFUL lot like this needing to be a type with a defined 
> conversion. 

Do you mean make `wraps` or `no_wraps` a type in the same way that 
[ext_vector_type](https://clang.llvm.org/docs/LanguageExtensions.html#vectors-and-extended-vectors)
 works? Or even BTFTagAttributedType?


https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Justin Stitt via cfe-commits


@@ -6664,6 +6664,13 @@ def err_builtin_counted_by_ref_invalid_lhs_use : Error<
 def err_builtin_counted_by_ref_has_side_effects : Error<
   "'__builtin_counted_by_ref' argument cannot have side-effects">;
 
+def warn_wraps_attr_var_decl_type_not_integer : Warning<
+  "using attribute '%select{wraps|no_wraps}0' with non-integer type '%1' has 
no function and is potentially misleading">,
+  InGroup;

JustinStitt wrote:

since this is now an error 
([3de3561](https://github.com/llvm/llvm-project/pull/115094/commits/3de3561f6c6e4e73ae1f5cda3a27a6aff5bf9904))
 we can be a bit more assertive with the language. I went with:

`cannot use attribute 'wraps' with non-integer type 'float'` which is an error 
when parsing.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Justin Stitt via cfe-commits


@@ -6664,6 +6664,13 @@ def err_builtin_counted_by_ref_invalid_lhs_use : Error<
 def err_builtin_counted_by_ref_has_side_effects : Error<
   "'__builtin_counted_by_ref' argument cannot have side-effects">;
 
+def warn_wraps_attr_var_decl_type_not_integer : Warning<

JustinStitt wrote:

Done in 
[3de3561](https://github.com/llvm/llvm-project/pull/115094/commits/3de3561f6c6e4e73ae1f5cda3a27a6aff5bf9904).
 Thanks

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Justin Stitt via cfe-commits


@@ -6536,6 +6536,30 @@ static void HandleBTFTypeTagAttribute(QualType &Type, 
const ParsedAttr &Attr,
   ::new (Ctx) BTFTypeTagAttr(Ctx, Attr, BTFTypeTag), Type);
 }
 
+static void handleWrapsAttr(QualType &Type, const ParsedAttr &Attr,
+TypeProcessingState &State, bool NoWraps = false) {
+  Sema &S = State.getSema();
+  ASTContext &Ctx = S.Context;
+
+  // wraps and no_wraps are most useful and consistent when used with C. Other
+  // languages have better alternatives within their type systems.
+  if (S.LangOpts.CPlusPlus || S.LangOpts.ObjC)

JustinStitt wrote:

For whatever reason, the execution still ends up here during parsing. Can't be 
an assert :(

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-12 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-11 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-11 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-11 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-11 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-11 Thread Justin Stitt via cfe-commits


@@ -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
+`_, ``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
+effectively re-enable instrumentation for specific types or variables.
+
+.. code-block:: c
+
+  typedef int __attribute__((no_wraps)) non_wrapping_int;
+
+  void foo(non_wrapping_int A, int B) {
+  ++A; // will be instrumented if built with 
-fsanitize=signed-integer-overflow
+  ++B; // won't be instrumented as it is ignored by the ignorelist
+  }
+
+Like ``wraps``, ``no_wraps`` persists through implicit type promotions and will
+be automatically applied to the result type of arithmetic expressions
+containing a wrapping operand.
+
+If a type or variable is attributed by both ``wraps`` and ``no_wraps``, then

JustinStitt wrote:

Since 
[093bb7f](https://github.com/llvm/llvm-project/pull/115094/commits/093bb7fe7a4bb86bb66c79d1173bc06e7c67c5e6),
 there is now an error when attributing both `wraps` and `no_wraps` to 
something:

```c
test.c:7:45: error: attribute 'wraps' cannot be used alongside 'no_wraps'
7 |   int __attribute__((wraps)) __attribute__((no_wraps)) A;
```

... and also there is no more "coming together naturally" of these attributes 
either. BinaryOperators will prefer capturing `no_wraps` over `wraps` and can 
only have one or the other. So, disregard my comment above.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-11 Thread Justin Stitt via cfe-commits

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

>From b5515eba87ffd96d010952bf18fe4044861df298 Mon Sep 17 00:00:00 2001
From: Justin Stitt 
Date: Tue, 5 Mar 2024 03:14:49 +
Subject: [PATCH 01/12] add wraps, no_wraps attributes

---
 clang/docs/ReleaseNotes.rst   |  20 
 clang/docs/SanitizerSpecialCaseList.rst   |   2 +
 clang/include/clang/AST/Expr.h|   6 ++
 clang/include/clang/AST/Type.h|   3 +
 clang/include/clang/Basic/Attr.td |  15 +++
 clang/include/clang/Basic/AttrDocs.td | 100 ++
 clang/include/clang/Basic/DiagnosticGroups.td |   6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   7 ++
 clang/lib/AST/Expr.cpp|  20 
 clang/lib/AST/ExprConstant.cpp|   4 +-
 clang/lib/AST/Type.cpp|   9 ++
 clang/lib/AST/TypePrinter.cpp |   6 ++
 clang/lib/CodeGen/CGExprScalar.cpp|  48 ++---
 clang/lib/Sema/Sema.cpp   |   3 +
 clang/lib/Sema/SemaChecking.cpp   |  35 +-
 clang/lib/Sema/SemaDecl.cpp   |   2 +-
 clang/lib/Sema/SemaDeclAttr.cpp   |  16 ++-
 clang/lib/Sema/SemaType.cpp   |  25 +
 clang/test/CodeGen/integer-overflow.c |  66 
 clang/test/CodeGen/unsigned-overflow.c|  63 +--
 clang/test/CodeGen/wraps-attribute-scl.test   |  78 ++
 ...a-attribute-supported-attributes-list.test |   2 +
 clang/test/Sema/attr-wraps.c  |  48 +
 23 files changed, 556 insertions(+), 28 deletions(-)
 create mode 100644 clang/test/CodeGen/wraps-attribute-scl.test
 create mode 100644 clang/test/Sema/attr-wraps.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0b0f2053f634ee..fd12e0e8d201d5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -433,6 +433,26 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow behavior for that expression as having
+  two's complement wrap-around. These expressions will not be instrumented by
+  overflow sanitizers nor will they cause integer overflow warnings. They also
+  cannot be optimized away by some eager UB optimizations as the behavior of
+  the arithmetic is no longer "undefined".
+
+  There is also ``__attribute__((no_wraps))`` which can be added to types or
+  variable declarations. Types or variables with this attribute may be
+  instrumented by overflow sanitizers, if enabled. Note that this matches the
+  default behavior of integer types. So, in most cases, ``no_wraps`` serves
+  purely as an annotation to readers of code that a type or variable really
+  shouldn't wrap-around. ``__attribute__((no_wraps))`` has the most function
+  when paired with `Sanitizer Special Case Lists (SSCL)
+  `_.
+
+  These attributes are only valid for C, as there are built-in language
+  alternatives for other languages.
+
 Improvements to Clang's diagnostics
 ---
 
diff --git a/clang/docs/SanitizerSpecialCaseList.rst 
b/clang/docs/SanitizerSpecialCaseList.rst
index 5c88c2976e8613..274409f47437c4 100644
--- a/clang/docs/SanitizerSpecialCaseList.rst
+++ b/clang/docs/SanitizerSpecialCaseList.rst
@@ -67,9 +67,11 @@ types specified within an ignorelist.
 int a = 2147483647; // INT_MAX
 ++a;// Normally, an overflow with 
-fsanitize=signed-integer-overflow
   }
+
   $ cat ignorelist.txt
   [signed-integer-overflow]
   type:int
+
   $ clang -fsanitize=signed-integer-overflow 
-fsanitize-ignorelist=ignorelist.txt foo.c ; ./a.out
   # no signed-integer-overflow error
 
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 466c65a9685ad3..4472c941ed5c79 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -4142,6 +4142,12 @@ class BinaryOperator : public Expr {
 return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
   }
 
+  /// Does one of the subexpressions have the wraps attribute?
+  bool hasWrappingOperand(const ASTContext &Ctx) const;
+
+  /// How about the no_wraps attribute?
+  bool hasNonWrappingOperand(const ASTContext &Ctx) const;
+
 protected:
   BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
  QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 8979129017163b..30217408856783 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/includ

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

2024-11-11 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-11 Thread Justin Stitt via cfe-commits


@@ -6664,6 +6664,13 @@ def err_builtin_counted_by_ref_invalid_lhs_use : Error<
 def err_builtin_counted_by_ref_has_side_effects : Error<
   "'__builtin_counted_by_ref' argument cannot have side-effects">;
 
+def warn_wraps_attr_var_decl_type_not_integer : Warning<
+  "using attribute '%select{wraps|no_wraps}0' with non-integer type '%1' has 
no function and is potentially misleading">,
+  InGroup;

JustinStitt wrote:

how about dropping "has no function and" so the final sentence becomes 
something like:

`"using attribute 'wraps' with non-integer type '%1' is potentially misleading"`
 

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Vitaly Buka via cfe-commits


@@ -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
+`_, ``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

vitalybuka wrote:

> But I see what you're saying about `__attribute__((sanitize(...)))`. Do you 
> think we should use `__attribute__((sanitize(...)))` instead of 
> `__attribute__((no_wraps))`? I think this may become confusing to users who 
> think this is turning on a sanitizer, which is not what it does; It really is 
> stating that something is "sanitizeable".
> 
> And for `wraps`, maybe you prefer `__attribute__((no_sanitize(...)))` over 
> `__attribute__((wraps))`?

Yes, if, like you said before, wraps is about disabling sanitizers, than 
`no_sanitize` looks better. We already can apply no_sanitizer(address) on some 
globals.

So, no_wraps(or sanitize) is here just to inverse ignore list for particular 
variable?
I don't think it's worth of it.

In general idea of sanitizers is to check code with minimal modification.
Some stuff required to avoid false-positives, but false-negatives we usually 
quite easy on them for sake of usability.
So if you need to suppress type, I don't think cherry-picking particular 
variables to suppress will have wide adoption, and may only annoy opposing 
users even more. 

Saying from my experience in google3, I would rather over-suppress than 
introduce additional burden.

BTW. you have "typedef" support in ignore list. Wouldn't e nicer just to change 
e.g type from e.g. int to sanitizer_int typedef or something?

So I see value in wraps/no_sanitize, but the reverse looks questionable.


https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits

JustinStitt wrote:

@erichkeane 
> Also, did we have an RFC on this? I'd like to see what the community at large 
> has to say.

Yes, here's the 
[RFC](https://discourse.llvm.org/t/rfc-add-wraps-attribute-for-granular-integer-overflow-handling/77670)
 and the [previous PR](https://github.com/llvm/llvm-project/pull/86618) (of 
which the scope has been expanded a bit so it deserves its own new PR, IMO)

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits


@@ -6536,6 +6536,30 @@ static void HandleBTFTypeTagAttribute(QualType &Type, 
const ParsedAttr &Attr,
   ::new (Ctx) BTFTypeTagAttr(Ctx, Attr, BTFTypeTag), Type);
 }
 
+static void handleWrapsAttr(QualType &Type, const ParsedAttr &Attr,
+TypeProcessingState &State, bool NoWraps = false) {
+  Sema &S = State.getSema();
+  ASTContext &Ctx = S.Context;
+
+  // wraps and no_wraps are most useful and consistent when used with C. Other
+  // languages have better alternatives within their type systems.
+  if (S.LangOpts.CPlusPlus || S.LangOpts.ObjC)

JustinStitt wrote:

I'm relying on the default diagnostic provided from the LangOpt `COnly` in the 
table gen. The message is the following:

```
test.cc:2:28: warning: 'wraps' attribute ignored [-Wignored-attributes]
2 | typedef int __attribute__((wraps)) wrapping_int;
  |^
1 warning generated.
```

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits


@@ -4852,6 +4862,10 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, 
Expr *lhs, Expr *rhs,
   if (hasStoredFPFeatures())
 setStoredFPFeatures(FPFeatures);
   setDependence(computeDependence(this));
+  if (hasWrappingOperand(Ctx))

JustinStitt wrote:

Implementation-wise, it is OK for both attributes to exist on the same type.

`hasWrapsAttr()` cautiously checks for `no_wraps` before claiming we have 
`wraps`.
```c
bool QualType::hasWrapsAttr() const {
  return !isNull() && getTypePtr()->hasAttr(attr::Wraps) &&
 !getTypePtr()->hasAttr(attr::NoWraps);
}

```

But yeah you're right, this is confusing because if you look at an ast dump 
you'll see both attributes applied to the type and it may not be obvious which 
has precedence. I'll add a diagnostic and a sane default of keeping the 
`no_wraps` and dropping `wraps` for cases like this.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Vitaly Buka via cfe-commits

https://github.com/vitalybuka edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Vitaly Buka via cfe-commits


@@ -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
+`_, ``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

vitalybuka wrote:

Patch itself, if we introduce wrap/no_sanitize, I don't think no_wrap/sanitize 
is a big problem for clang maintainers. They may think otherwise :)

However, this just smells like YAGNI to me.

I would see Linux roll-out, as multi step process:
1. Roll-out with over-suppression: ignore list and no_sanitizer attribute.
2. If Linux is able to keep up with those checks, maybe reduce suppression 
scope with available tools.
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.



https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Vitaly Buka via cfe-commits

https://github.com/vitalybuka edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Vitaly Buka via cfe-commits

https://github.com/vitalybuka edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Erich Keane via cfe-commits


@@ -6664,6 +6664,13 @@ def err_builtin_counted_by_ref_invalid_lhs_use : Error<
 def err_builtin_counted_by_ref_has_side_effects : Error<
   "'__builtin_counted_by_ref' argument cannot have side-effects">;
 
+def warn_wraps_attr_var_decl_type_not_integer : Warning<

erichkeane wrote:

This should be an error, mishandling an attribute like this should stop 
compilation.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Erich Keane via cfe-commits


@@ -4852,6 +4862,10 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, 
Expr *lhs, Expr *rhs,
   if (hasStoredFPFeatures())
 setStoredFPFeatures(FPFeatures);
   setDependence(computeDependence(this));
+  if (hasWrappingOperand(Ctx))

erichkeane wrote:

This can result in BOTH things happening!  Should this be a diagnostic? (trying 
to do BOTH a wraps and a no_wraps here?).

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Erich Keane via cfe-commits


@@ -6664,6 +6664,13 @@ def err_builtin_counted_by_ref_invalid_lhs_use : Error<
 def err_builtin_counted_by_ref_has_side_effects : Error<
   "'__builtin_counted_by_ref' argument cannot have side-effects">;
 
+def warn_wraps_attr_var_decl_type_not_integer : Warning<
+  "using attribute '%select{wraps|no_wraps}0' with non-integer type '%1' has 
no function and is potentially misleading">,
+  InGroup;

erichkeane wrote:

Phrasing on this isn't great, the diagnostic could be worded more consistently. 
 Bikesheds welcome.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Erich Keane via cfe-commits


@@ -6536,6 +6536,30 @@ static void HandleBTFTypeTagAttribute(QualType &Type, 
const ParsedAttr &Attr,
   ::new (Ctx) BTFTypeTagAttr(Ctx, Attr, BTFTypeTag), Type);
 }
 
+static void handleWrapsAttr(QualType &Type, const ParsedAttr &Attr,
+TypeProcessingState &State, bool NoWraps = false) {
+  Sema &S = State.getSema();
+  ASTContext &Ctx = S.Context;
+
+  // wraps and no_wraps are most useful and consistent when used with C. Other
+  // languages have better alternatives within their type systems.
+  if (S.LangOpts.CPlusPlus || S.LangOpts.ObjC)

erichkeane wrote:

This should diagnose.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Erich Keane via cfe-commits

https://github.com/erichkeane commented:

It seems to me that this should just modify the type, rather than risk getting 
lost like it does.  If you want to define the conversion to the underlying 
integer type(likely via cast!) that is sensible as well, but this is going to 
end up getting lost pretty easily, so likely worth trying to see if this is 
worht a new type in the AST.

Also, did we have an RFC on this?  I'd like to see what the community at large 
has to say.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Erich Keane via cfe-commits


@@ -4870,6 +4884,10 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, 
Expr *lhs, Expr *rhs,
   if (hasStoredFPFeatures())
 setStoredFPFeatures(FPFeatures);
   setDependence(computeDependence(this));
+  if (hasWrappingOperand(Ctx))

erichkeane wrote:

Same problem here.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Erich Keane via cfe-commits


@@ -2863,6 +2863,15 @@ bool QualType::isWebAssemblyFuncrefType() const {
  getAddressSpace() == LangAS::wasm_funcref;
 }
 
+bool QualType::hasWrapsAttr() const {
+  return !isNull() && getTypePtr()->hasAttr(attr::Wraps) &&

erichkeane wrote:

we probably want to do 'more work' to pull out the type you want/canonicalize 
the type here.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Erich Keane via cfe-commits


@@ -10818,11 +10819,39 @@ static bool IsImplicitBoolFloatConversion(Sema &S, 
Expr *Ex, bool ToBool) {
   FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
 }
 
+/// Check to see if the wraps or no_wraps attribute may have been lost through
+/// a function call. For cases where we are unsure, assume not.
+static bool IsWrapsAttrLost(Sema &S, const CallExpr *TheCall,
+const FunctionDecl *FD, unsigned i) {
+  // We may not have a FunctionDecl if this CallExpr is associated virtual,
+  // templated or overloaded functions.
+  if (!FD)
+return false;
+
+  if (i >= TheCall->getNumArgs() || i >= FD->getNumParams())
+return false;
+
+  const QualType ProvidedArgTy = TheCall->getArg(i)->getType();
+  const QualType PrototypedArgTy = FD->getParamDecl(i)->getType();
+
+  return (ProvidedArgTy.hasWrapsAttr() && !PrototypedArgTy.hasWrapsAttr()) ||
+ (ProvidedArgTy.hasNoWrapsAttr() && !PrototypedArgTy.hasNoWrapsAttr());
+}
+
 static void CheckImplicitArgumentConversions(Sema &S, CallExpr *TheCall,
  SourceLocation CC) {
   unsigned NumArgs = TheCall->getNumArgs();
+  const FunctionDecl *FD = TheCall->getDirectCallee();
+
   for (unsigned i = 0; i < NumArgs; ++i) {
 Expr *CurrA = TheCall->getArg(i);
+
+if (IsWrapsAttrLost(S, TheCall, FD, i))

erichkeane wrote:

This is looking an AWFUL lot like this needing to be a type with a defined 
conversion.  I don't think `AttributedType` is sufficient here, this should 
also probably be a diagnosed-error, which you get when it is a part of the 
actual type.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Erich Keane via cfe-commits

https://github.com/erichkeane edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits


@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -triple x86_64-pc-linux-gnu
+typedef int __attribute__((wraps)) wrapping_int;

JustinStitt wrote:

> Can we test more types?

Yes, I'll add some more tests 😄 

> 
> Can the attributes be applied to pointers? Both the pointer itself and the 
> pointee? It's worth adding tests, just to ensure nothing regresses here.

Pointers no:
```
warning: using attribute 'wraps' with non-integer type 'char *' has no function 
and is potentially misleading [-Wuseless-wraps-attribute]
2 |   char *A __attribute__((wraps));
```

pointees yes:
```
  char B __attribute__((wraps)) = 127;
  char *A = &B;
  (++B); // no -fsanitize=implicit-signed-integer-truncation splat!
```



https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits


@@ -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

JustinStitt wrote:

Yes, good idea.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits


@@ -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
+`_, ``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:

But I see what you're saying about `__attribute__((sanitize(...)))`. Do you 
think we should use `__attribute__((sanitize(...)))` instead of 
`__attribute__((no_wraps))`? I think this may become confusing to users who 
think this is turning on a sanitizer, which is not what it does; It really is 
stating that something is "sanitizeable".

And for `wraps`, maybe you prefer `__attribute__((no_sanitize(...)))` over 
`__attribute__((wraps))`?

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits


@@ -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
+`_, ``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:

Read my other comments about `no_wraps` + SSCLs and recovery modes. I don't 
think any consideration to recovery modes should be made from `wraps` or 
`no_wraps`. These attributes only care about sanitizer instrumentation and 
_not_ the handling thereof.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits


@@ -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

JustinStitt wrote:

The entire intention of `wraps` is to _disable_ instrumentation entirely. We 
never want a report or trap out of such expressions. Developers who have very 
intentional wrapping arithmetic should be able to delegate types as "wrapping" 
and move on with their day.

Furthermore, most of the use of `no_wraps` is in conjunction with SSCLs to 
further control overflow behavior at the type-level. Sanitizer recovery modes 
remain separate from all of this.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits


@@ -433,6 +433,26 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow behavior for that expression as having
+  two's complement wrap-around. These expressions will not be instrumented by
+  overflow sanitizers nor will they cause integer overflow warnings. They also
+  cannot be optimized away by some eager UB optimizations as the behavior of
+  the arithmetic is no longer "undefined".
+
+  There is also ``__attribute__((no_wraps))`` which can be added to types or
+  variable declarations. Types or variables with this attribute may be
+  instrumented by overflow sanitizers, if enabled. Note that this matches the
+  default behavior of integer types. So, in most cases, ``no_wraps`` serves

JustinStitt wrote:

When used alongside very strict SSCLs there is great utility to be gained from 
`no_wraps`.

In the kernel we want to use an SSCL ignorelist like this:
```
[{signed-integer-overflow,unsigned-integer-overflow}]
type:*
```

then annotate specific types like `size_t` in source:

``` cpp
typedef __kernel_size_tsize_t __attribute__((no_wraps));
```


https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits


@@ -67,9 +67,11 @@ types specified within an ignorelist.
 int a = 2147483647; // INT_MAX
 ++a;// Normally, an overflow with 
-fsanitize=signed-integer-overflow
   }
+

JustinStitt wrote:

I don't have commit access, but I'll revert that whitespace change 👍 

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Vitaly Buka via cfe-commits

https://github.com/vitalybuka edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Vitaly Buka via cfe-commits


@@ -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
+`_, ``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

vitalybuka wrote:

I think wrap and sanitize should be independent, because of "recover" mode.
In this case no_wraps is redundant, unless it's going to override -fwrap.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Vitaly Buka via cfe-commits

https://github.com/vitalybuka commented:

I guess we already discussed that before. My preference is the wrap and 
sanitize attributes are interdependent. Open to be convinced otherwise.

But seems like we want consistency with https://godbolt.org/z/crhdaczx1

* `__attribute__((wraps,no_sanitize("signed-integer-overflow")))` wraps quietly
* `__attribute__((wraps))`  wraps, but may report if runs with 
`-fsanitize=signed-integer-overflow`
* `__attribute__((no_sanitize("signed-integer-overflow")))` reports, but in 
recovery mode, compile UB any way it likes.


https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Vitaly Buka via cfe-commits


@@ -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

vitalybuka wrote:

I don't think it should affect instrumentation at all.
We have -fsanitize-recover= mode.
In this case we need instrumentation to print report, regardless of "wrap", and 
the "wrap" or -fwrap will control how to calculate after the report.

to suppress report we have no_sanitize attribute already

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Vitaly Buka via cfe-commits


@@ -433,6 +433,26 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow behavior for that expression as having
+  two's complement wrap-around. These expressions will not be instrumented by
+  overflow sanitizers nor will they cause integer overflow warnings. They also
+  cannot be optimized away by some eager UB optimizations as the behavior of
+  the arithmetic is no longer "undefined".
+
+  There is also ``__attribute__((no_wraps))`` which can be added to types or
+  variable declarations. Types or variables with this attribute may be
+  instrumented by overflow sanitizers, if enabled. Note that this matches the
+  default behavior of integer types. So, in most cases, ``no_wraps`` serves

vitalybuka wrote:

So this is essentially no opt?
I don't thing this will help, to me it will trigger readers to think what it's 
needed, unnecessary noise.
Regular comment will be as good enough?



https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Vitaly Buka via cfe-commits


@@ -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

vitalybuka wrote:

should we mention that it's `-fwrap` equivalent

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Vitaly Buka via cfe-commits

https://github.com/vitalybuka edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Vitaly Buka via cfe-commits


@@ -67,9 +67,11 @@ types specified within an ignorelist.
 int a = 2147483647; // INT_MAX
 ++a;// Normally, an overflow with 
-fsanitize=signed-integer-overflow
   }
+

vitalybuka wrote:

Yes, I'ts about spaces. Even if it's useful change  just create a new PR. Even 
from web UI. If you had commit access, no review is needed.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Vitaly Buka via cfe-commits

vitalybuka wrote:

I am comfortable accepting sanitization related stuff, and will be happy to 
look into implementation details.
To me this approach is LGTM, but this patch goes beyond sanitizers into the 
area of tuning behavior of UB code,
so I think we need feedback from maintainers of the related code @erichkeane, 
@efriedma-quic.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits


@@ -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
+`_, ``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
+effectively re-enable instrumentation for specific types or variables.
+
+.. code-block:: c
+
+  typedef int __attribute__((no_wraps)) non_wrapping_int;
+
+  void foo(non_wrapping_int A, int B) {
+  ++A; // will be instrumented if built with 
-fsanitize=signed-integer-overflow
+  ++B; // won't be instrumented as it is ignored by the ignorelist
+  }
+
+Like ``wraps``, ``no_wraps`` persists through implicit type promotions and will
+be automatically applied to the result type of arithmetic expressions
+containing a wrapping operand.
+
+If a type or variable is attributed by both ``wraps`` and ``no_wraps``, then
+``no_wraps`` takes precedence -- regardless of the order of attribution.
+
+Note that ``no_wraps`` makes no guarantees about the definedness of arithmetic

JustinStitt wrote:

The "definedness" of signed overflow is handled at the language level with 
things like `-fwrapv` or `-fno-wrapv`.

Usually codebases opt for `-fwrapv` to avoid eager optimizations of UB 
arithmetic, think of stuff like:

```c
if (a + 1 < a) { ... }
```

which might be completely optimized away without `-fwrapv`.

I didn't really want things marked with `no_wraps` to go against what users 
have specified with `-fwrapv` and their code starts getting optimized away. 
`wraps` and `no_wraps` are intended to be used to modify sanitizer 
instrumentation and not entire language properties.

If `no_wraps` went against `-fwrapv` then I know for a fact the kernel would 
not use it, and we really need it over there.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits


@@ -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
+`_, ``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
+effectively re-enable instrumentation for specific types or variables.
+
+.. code-block:: c
+
+  typedef int __attribute__((no_wraps)) non_wrapping_int;
+
+  void foo(non_wrapping_int A, int B) {
+  ++A; // will be instrumented if built with 
-fsanitize=signed-integer-overflow
+  ++B; // won't be instrumented as it is ignored by the ignorelist
+  }
+
+Like ``wraps``, ``no_wraps`` persists through implicit type promotions and will
+be automatically applied to the result type of arithmetic expressions
+containing a wrapping operand.
+
+If a type or variable is attributed by both ``wraps`` and ``no_wraps``, then

JustinStitt wrote:

> Is there a requirement for this somewhere that these can be mixed?

Mixing these intentionally is not something you'd want to do. However, these 
attributes can come together organically:

```c
void foo(int __attribute__((wraps)) A, int __attribute__((no_wraps)) B) {
  (A + B);
}
```

Resulting in the following AST:

```
.-FunctionDecl 0x556f503f4400  line:2:6 foo 'void (int 
__attribute__((wraps)), int __attribute__((no_wraps)))'
  |-ParmVarDecl 0x556f503f41f0  col:37 used A 'int 
__attribute__((wraps))':'int'
  |-ParmVarDecl 0x556f503f42e0  col:70 used B 'int 
__attribute__((no_wraps))':'int'
  .-CompoundStmt 0x556f503f4630 
.-ParenExpr 0x556f503f4610  'int __attribute__((wraps)) 
__attribute__((no_wraps))':'int'
  .-BinaryOperator 0x556f503f4570  'int 
__attribute__((wraps)) __attribute__((no_wraps))':'int' '+'
|-ImplicitCastExpr 0x556f503f4540  'int 
__attribute__((wraps))':'int' 
| .-DeclRefExpr 0x556f503f4500  'int 
__attribute__((wraps))':'int' lvalue ParmVar 0x556f503f41f0 'A' 'int 
__attribute__((wraps))':'int'
.-ImplicitCastExpr 0x556f503f4558  'int 
__attribute__((no_wraps))':'int' 
  .-DeclRefExpr 0x556f503f4520  'int 
__attribute__((no_wraps))':'int' lvalue ParmVar 0x556f503f42e0 'B' 'int 
__attribute__((no_wraps))':'int'

```

Notice

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

2024-11-08 Thread Justin Stitt via cfe-commits


@@ -433,6 +433,26 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow behavior for that expression as having
+  two's complement wrap-around. These expressions will not be instrumented by
+  overflow sanitizers nor will they cause integer overflow warnings. They also
+  cannot be optimized away by some eager UB optimizations as the behavior of
+  the arithmetic is no longer "undefined".
+
+  There is also ``__attribute__((no_wraps))`` which can be added to types or
+  variable declarations. Types or variables with this attribute may be
+  instrumented by overflow sanitizers, if enabled. Note that this matches the
+  default behavior of integer types. So, in most cases, ``no_wraps`` serves
+  purely as an annotation to readers of code that a type or variable really
+  shouldn't wrap-around. ``__attribute__((no_wraps))`` has the most function
+  when paired with `Sanitizer Special Case Lists (SSCL)
+  `_.
+
+  These attributes are only valid for C, as there are built-in language

JustinStitt wrote:

I guess it wouldn't be the worst idea to just let the attribute exist in C++ 
and document common breakages? We should really urge C++ users to use the type 
system and operator overloading to their advantage, though, and not use 
wraps/no_wraps.

What do we think?

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Justin Stitt via cfe-commits


@@ -433,6 +433,26 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow behavior for that expression as having
+  two's complement wrap-around. These expressions will not be instrumented by
+  overflow sanitizers nor will they cause integer overflow warnings. They also
+  cannot be optimized away by some eager UB optimizations as the behavior of
+  the arithmetic is no longer "undefined".
+
+  There is also ``__attribute__((no_wraps))`` which can be added to types or
+  variable declarations. Types or variables with this attribute may be
+  instrumented by overflow sanitizers, if enabled. Note that this matches the
+  default behavior of integer types. So, in most cases, ``no_wraps`` serves
+  purely as an annotation to readers of code that a type or variable really
+  shouldn't wrap-around. ``__attribute__((no_wraps))`` has the most function
+  when paired with `Sanitizer Special Case Lists (SSCL)
+  `_.
+
+  These attributes are only valid for C, as there are built-in language

JustinStitt wrote:

No, it won't break the build. You will get an ignored attribute warning and the 
attributes won't be applied or have any effect. (I'll document this).

These attributes are relatively well supported in C++ but that language has 
many more ways for the attribute to disappear unexpectedly. 

This attribute is mostly needed in C (as there aren't any alternatives).

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Marco Elver via cfe-commits


@@ -433,6 +433,26 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow behavior for that expression as having
+  two's complement wrap-around. These expressions will not be instrumented by
+  overflow sanitizers nor will they cause integer overflow warnings. They also
+  cannot be optimized away by some eager UB optimizations as the behavior of
+  the arithmetic is no longer "undefined".
+
+  There is also ``__attribute__((no_wraps))`` which can be added to types or
+  variable declarations. Types or variables with this attribute may be
+  instrumented by overflow sanitizers, if enabled. Note that this matches the
+  default behavior of integer types. So, in most cases, ``no_wraps`` serves
+  purely as an annotation to readers of code that a type or variable really
+  shouldn't wrap-around. ``__attribute__((no_wraps))`` has the most function
+  when paired with `Sanitizer Special Case Lists (SSCL)
+  `_.
+
+  These attributes are only valid for C, as there are built-in language

melver wrote:

If the attribute is used with C++ code will it break the build?
I.e. if someone includes a C header into a C++ project that uses these 
attributes, are we going to run into problems? If yes, this doesn't sound right 
to me.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Marco Elver via cfe-commits


@@ -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
+`_, ``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
+effectively re-enable instrumentation for specific types or variables.
+
+.. code-block:: c
+
+  typedef int __attribute__((no_wraps)) non_wrapping_int;
+
+  void foo(non_wrapping_int A, int B) {
+  ++A; // will be instrumented if built with 
-fsanitize=signed-integer-overflow
+  ++B; // won't be instrumented as it is ignored by the ignorelist
+  }
+
+Like ``wraps``, ``no_wraps`` persists through implicit type promotions and will
+be automatically applied to the result type of arithmetic expressions
+containing a wrapping operand.
+
+If a type or variable is attributed by both ``wraps`` and ``no_wraps``, then
+``no_wraps`` takes precedence -- regardless of the order of attribution.
+
+Note that ``no_wraps`` makes no guarantees about the definedness of arithmetic

melver wrote:

This sentence is confusing. Is that implied that if I add `no_wraps`, that 
overflow is now UB? Why does fwrapv help here?

In general, I think there need to be more explicit mentions of -fwrapv and how 
these attribtues interact with these flags - afaik the attributes give us 
selective fwrapv and fno-wrapv respectively.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Marco Elver via cfe-commits


@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -triple x86_64-pc-linux-gnu
+typedef int __attribute__((wraps)) wrapping_int;

melver wrote:

Can we test more types?

Can the attributes be applied to pointers? Both the pointer itself and the 
pointee? It's worth adding tests, just to ensure nothing regresses here.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Marco Elver via cfe-commits

https://github.com/melver requested changes to this pull request.


https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-08 Thread Marco Elver via cfe-commits


@@ -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
+`_, ``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
+effectively re-enable instrumentation for specific types or variables.
+
+.. code-block:: c
+
+  typedef int __attribute__((no_wraps)) non_wrapping_int;
+
+  void foo(non_wrapping_int A, int B) {
+  ++A; // will be instrumented if built with 
-fsanitize=signed-integer-overflow
+  ++B; // won't be instrumented as it is ignored by the ignorelist
+  }
+
+Like ``wraps``, ``no_wraps`` persists through implicit type promotions and will
+be automatically applied to the result type of arithmetic expressions
+containing a wrapping operand.
+
+If a type or variable is attributed by both ``wraps`` and ``no_wraps``, then

melver wrote:

Is there a requirement for this somewhere that these can be mixed?

It would seem more intuitive to me to produce a warning if both are applied and 
effectively pretend neither attribute is specified because whoever applied the 
attributes is confused.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-07 Thread Justin Stitt via cfe-commits

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

>From b5515eba87ffd96d010952bf18fe4044861df298 Mon Sep 17 00:00:00 2001
From: Justin Stitt 
Date: Tue, 5 Mar 2024 03:14:49 +
Subject: [PATCH 1/6] add wraps, no_wraps attributes

---
 clang/docs/ReleaseNotes.rst   |  20 
 clang/docs/SanitizerSpecialCaseList.rst   |   2 +
 clang/include/clang/AST/Expr.h|   6 ++
 clang/include/clang/AST/Type.h|   3 +
 clang/include/clang/Basic/Attr.td |  15 +++
 clang/include/clang/Basic/AttrDocs.td | 100 ++
 clang/include/clang/Basic/DiagnosticGroups.td |   6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   7 ++
 clang/lib/AST/Expr.cpp|  20 
 clang/lib/AST/ExprConstant.cpp|   4 +-
 clang/lib/AST/Type.cpp|   9 ++
 clang/lib/AST/TypePrinter.cpp |   6 ++
 clang/lib/CodeGen/CGExprScalar.cpp|  48 ++---
 clang/lib/Sema/Sema.cpp   |   3 +
 clang/lib/Sema/SemaChecking.cpp   |  35 +-
 clang/lib/Sema/SemaDecl.cpp   |   2 +-
 clang/lib/Sema/SemaDeclAttr.cpp   |  16 ++-
 clang/lib/Sema/SemaType.cpp   |  25 +
 clang/test/CodeGen/integer-overflow.c |  66 
 clang/test/CodeGen/unsigned-overflow.c|  63 +--
 clang/test/CodeGen/wraps-attribute-scl.test   |  78 ++
 ...a-attribute-supported-attributes-list.test |   2 +
 clang/test/Sema/attr-wraps.c  |  48 +
 23 files changed, 556 insertions(+), 28 deletions(-)
 create mode 100644 clang/test/CodeGen/wraps-attribute-scl.test
 create mode 100644 clang/test/Sema/attr-wraps.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0b0f2053f634eea..fd12e0e8d201d5f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -433,6 +433,26 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow behavior for that expression as having
+  two's complement wrap-around. These expressions will not be instrumented by
+  overflow sanitizers nor will they cause integer overflow warnings. They also
+  cannot be optimized away by some eager UB optimizations as the behavior of
+  the arithmetic is no longer "undefined".
+
+  There is also ``__attribute__((no_wraps))`` which can be added to types or
+  variable declarations. Types or variables with this attribute may be
+  instrumented by overflow sanitizers, if enabled. Note that this matches the
+  default behavior of integer types. So, in most cases, ``no_wraps`` serves
+  purely as an annotation to readers of code that a type or variable really
+  shouldn't wrap-around. ``__attribute__((no_wraps))`` has the most function
+  when paired with `Sanitizer Special Case Lists (SSCL)
+  `_.
+
+  These attributes are only valid for C, as there are built-in language
+  alternatives for other languages.
+
 Improvements to Clang's diagnostics
 ---
 
diff --git a/clang/docs/SanitizerSpecialCaseList.rst 
b/clang/docs/SanitizerSpecialCaseList.rst
index 5c88c2976e86139..274409f47437c45 100644
--- a/clang/docs/SanitizerSpecialCaseList.rst
+++ b/clang/docs/SanitizerSpecialCaseList.rst
@@ -67,9 +67,11 @@ types specified within an ignorelist.
 int a = 2147483647; // INT_MAX
 ++a;// Normally, an overflow with 
-fsanitize=signed-integer-overflow
   }
+
   $ cat ignorelist.txt
   [signed-integer-overflow]
   type:int
+
   $ clang -fsanitize=signed-integer-overflow 
-fsanitize-ignorelist=ignorelist.txt foo.c ; ./a.out
   # no signed-integer-overflow error
 
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 466c65a9685ad32..4472c941ed5c798 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -4142,6 +4142,12 @@ class BinaryOperator : public Expr {
 return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
   }
 
+  /// Does one of the subexpressions have the wraps attribute?
+  bool hasWrappingOperand(const ASTContext &Ctx) const;
+
+  /// How about the no_wraps attribute?
+  bool hasNonWrappingOperand(const ASTContext &Ctx) const;
+
 protected:
   BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
  QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 8979129017163b6..30217408856783f 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/

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

2024-11-07 Thread Justin Stitt via cfe-commits

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

>From f58e6481650f8cda6089b2a0637c94596a45370e Mon Sep 17 00:00:00 2001
From: Justin Stitt 
Date: Tue, 5 Mar 2024 03:14:49 +
Subject: [PATCH 1/6] add wraps, no_wraps attributes

---
 clang/docs/ReleaseNotes.rst   |  20 
 clang/docs/SanitizerSpecialCaseList.rst   |   2 +
 clang/include/clang/AST/Expr.h|   6 ++
 clang/include/clang/AST/Type.h|   3 +
 clang/include/clang/Basic/Attr.td |  15 +++
 clang/include/clang/Basic/AttrDocs.td | 100 ++
 clang/include/clang/Basic/DiagnosticGroups.td |   6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   7 ++
 clang/lib/AST/Expr.cpp|  20 
 clang/lib/AST/ExprConstant.cpp|   4 +-
 clang/lib/AST/Type.cpp|   9 ++
 clang/lib/AST/TypePrinter.cpp |   6 ++
 clang/lib/CodeGen/CGExprScalar.cpp|  48 ++---
 clang/lib/Sema/Sema.cpp   |   3 +
 clang/lib/Sema/SemaChecking.cpp   |  35 +-
 clang/lib/Sema/SemaDecl.cpp   |   2 +-
 clang/lib/Sema/SemaDeclAttr.cpp   |  16 ++-
 clang/lib/Sema/SemaType.cpp   |  25 +
 clang/test/CodeGen/integer-overflow.c |  66 
 clang/test/CodeGen/unsigned-overflow.c|  63 +--
 clang/test/CodeGen/wraps-attribute-scl.test   |  78 ++
 ...a-attribute-supported-attributes-list.test |   2 +
 clang/test/Sema/attr-wraps.c  |  48 +
 23 files changed, 556 insertions(+), 28 deletions(-)
 create mode 100644 clang/test/CodeGen/wraps-attribute-scl.test
 create mode 100644 clang/test/Sema/attr-wraps.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index dc45202f6b2e86..5457d802d820f3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -386,6 +386,26 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow behavior for that expression as having
+  two's complement wrap-around. These expressions will not be instrumented by
+  overflow sanitizers nor will they cause integer overflow warnings. They also
+  cannot be optimized away by some eager UB optimizations as the behavior of
+  the arithmetic is no longer "undefined".
+
+  There is also ``__attribute__((no_wraps))`` which can be added to types or
+  variable declarations. Types or variables with this attribute may be
+  instrumented by overflow sanitizers, if enabled. Note that this matches the
+  default behavior of integer types. So, in most cases, ``no_wraps`` serves
+  purely as an annotation to readers of code that a type or variable really
+  shouldn't wrap-around. ``__attribute__((no_wraps))`` has the most function
+  when paired with `Sanitizer Special Case Lists (SSCL)
+  `_.
+
+  These attributes are only valid for C, as there are built-in language
+  alternatives for other languages.
+
 Improvements to Clang's diagnostics
 ---
 
diff --git a/clang/docs/SanitizerSpecialCaseList.rst 
b/clang/docs/SanitizerSpecialCaseList.rst
index 96a7b2fba4ae43..10462643b69c7f 100644
--- a/clang/docs/SanitizerSpecialCaseList.rst
+++ b/clang/docs/SanitizerSpecialCaseList.rst
@@ -67,9 +67,11 @@ types specified within an ignorelist.
 int a = 2147483647; // INT_MAX
 ++a;// Normally, an overflow with 
-fsanitize=signed-integer-overflow
   }
+
   $ cat ignorelist.txt
   [signed-integer-overflow]
   type:int
+
   $ clang -fsanitize=signed-integer-overflow 
-fsanitize-ignorelist=ignorelist.txt foo.c ; ./a.out
   # no signed-integer-overflow error
 
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 466c65a9685ad3..4472c941ed5c79 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -4142,6 +4142,12 @@ class BinaryOperator : public Expr {
 return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
   }
 
+  /// Does one of the subexpressions have the wraps attribute?
+  bool hasWrappingOperand(const ASTContext &Ctx) const;
+
+  /// How about the no_wraps attribute?
+  bool hasNonWrappingOperand(const ASTContext &Ctx) const;
+
 protected:
   BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
  QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 1bcc7ee0b70dee..c7f368c0193664 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/

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

2024-11-06 Thread Justin Stitt via cfe-commits

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

>From f58e6481650f8cda6089b2a0637c94596a45370e Mon Sep 17 00:00:00 2001
From: Justin Stitt 
Date: Tue, 5 Mar 2024 03:14:49 +
Subject: [PATCH 1/5] add wraps, no_wraps attributes

---
 clang/docs/ReleaseNotes.rst   |  20 
 clang/docs/SanitizerSpecialCaseList.rst   |   2 +
 clang/include/clang/AST/Expr.h|   6 ++
 clang/include/clang/AST/Type.h|   3 +
 clang/include/clang/Basic/Attr.td |  15 +++
 clang/include/clang/Basic/AttrDocs.td | 100 ++
 clang/include/clang/Basic/DiagnosticGroups.td |   6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   7 ++
 clang/lib/AST/Expr.cpp|  20 
 clang/lib/AST/ExprConstant.cpp|   4 +-
 clang/lib/AST/Type.cpp|   9 ++
 clang/lib/AST/TypePrinter.cpp |   6 ++
 clang/lib/CodeGen/CGExprScalar.cpp|  48 ++---
 clang/lib/Sema/Sema.cpp   |   3 +
 clang/lib/Sema/SemaChecking.cpp   |  35 +-
 clang/lib/Sema/SemaDecl.cpp   |   2 +-
 clang/lib/Sema/SemaDeclAttr.cpp   |  16 ++-
 clang/lib/Sema/SemaType.cpp   |  25 +
 clang/test/CodeGen/integer-overflow.c |  66 
 clang/test/CodeGen/unsigned-overflow.c|  63 +--
 clang/test/CodeGen/wraps-attribute-scl.test   |  78 ++
 ...a-attribute-supported-attributes-list.test |   2 +
 clang/test/Sema/attr-wraps.c  |  48 +
 23 files changed, 556 insertions(+), 28 deletions(-)
 create mode 100644 clang/test/CodeGen/wraps-attribute-scl.test
 create mode 100644 clang/test/Sema/attr-wraps.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index dc45202f6b2e86..5457d802d820f3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -386,6 +386,26 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow behavior for that expression as having
+  two's complement wrap-around. These expressions will not be instrumented by
+  overflow sanitizers nor will they cause integer overflow warnings. They also
+  cannot be optimized away by some eager UB optimizations as the behavior of
+  the arithmetic is no longer "undefined".
+
+  There is also ``__attribute__((no_wraps))`` which can be added to types or
+  variable declarations. Types or variables with this attribute may be
+  instrumented by overflow sanitizers, if enabled. Note that this matches the
+  default behavior of integer types. So, in most cases, ``no_wraps`` serves
+  purely as an annotation to readers of code that a type or variable really
+  shouldn't wrap-around. ``__attribute__((no_wraps))`` has the most function
+  when paired with `Sanitizer Special Case Lists (SSCL)
+  `_.
+
+  These attributes are only valid for C, as there are built-in language
+  alternatives for other languages.
+
 Improvements to Clang's diagnostics
 ---
 
diff --git a/clang/docs/SanitizerSpecialCaseList.rst 
b/clang/docs/SanitizerSpecialCaseList.rst
index 96a7b2fba4ae43..10462643b69c7f 100644
--- a/clang/docs/SanitizerSpecialCaseList.rst
+++ b/clang/docs/SanitizerSpecialCaseList.rst
@@ -67,9 +67,11 @@ types specified within an ignorelist.
 int a = 2147483647; // INT_MAX
 ++a;// Normally, an overflow with 
-fsanitize=signed-integer-overflow
   }
+
   $ cat ignorelist.txt
   [signed-integer-overflow]
   type:int
+
   $ clang -fsanitize=signed-integer-overflow 
-fsanitize-ignorelist=ignorelist.txt foo.c ; ./a.out
   # no signed-integer-overflow error
 
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 466c65a9685ad3..4472c941ed5c79 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -4142,6 +4142,12 @@ class BinaryOperator : public Expr {
 return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
   }
 
+  /// Does one of the subexpressions have the wraps attribute?
+  bool hasWrappingOperand(const ASTContext &Ctx) const;
+
+  /// How about the no_wraps attribute?
+  bool hasNonWrappingOperand(const ASTContext &Ctx) const;
+
 protected:
   BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
  QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 1bcc7ee0b70dee..c7f368c0193664 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/

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

2024-11-06 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-06 Thread Justin Stitt via cfe-commits

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

>From f58e6481650f8cda6089b2a0637c94596a45370e Mon Sep 17 00:00:00 2001
From: Justin Stitt 
Date: Tue, 5 Mar 2024 03:14:49 +
Subject: [PATCH 1/6] add wraps, no_wraps attributes

---
 clang/docs/ReleaseNotes.rst   |  20 
 clang/docs/SanitizerSpecialCaseList.rst   |   2 +
 clang/include/clang/AST/Expr.h|   6 ++
 clang/include/clang/AST/Type.h|   3 +
 clang/include/clang/Basic/Attr.td |  15 +++
 clang/include/clang/Basic/AttrDocs.td | 100 ++
 clang/include/clang/Basic/DiagnosticGroups.td |   6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   7 ++
 clang/lib/AST/Expr.cpp|  20 
 clang/lib/AST/ExprConstant.cpp|   4 +-
 clang/lib/AST/Type.cpp|   9 ++
 clang/lib/AST/TypePrinter.cpp |   6 ++
 clang/lib/CodeGen/CGExprScalar.cpp|  48 ++---
 clang/lib/Sema/Sema.cpp   |   3 +
 clang/lib/Sema/SemaChecking.cpp   |  35 +-
 clang/lib/Sema/SemaDecl.cpp   |   2 +-
 clang/lib/Sema/SemaDeclAttr.cpp   |  16 ++-
 clang/lib/Sema/SemaType.cpp   |  25 +
 clang/test/CodeGen/integer-overflow.c |  66 
 clang/test/CodeGen/unsigned-overflow.c|  63 +--
 clang/test/CodeGen/wraps-attribute-scl.test   |  78 ++
 ...a-attribute-supported-attributes-list.test |   2 +
 clang/test/Sema/attr-wraps.c  |  48 +
 23 files changed, 556 insertions(+), 28 deletions(-)
 create mode 100644 clang/test/CodeGen/wraps-attribute-scl.test
 create mode 100644 clang/test/Sema/attr-wraps.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index dc45202f6b2e86..5457d802d820f3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -386,6 +386,26 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow behavior for that expression as having
+  two's complement wrap-around. These expressions will not be instrumented by
+  overflow sanitizers nor will they cause integer overflow warnings. They also
+  cannot be optimized away by some eager UB optimizations as the behavior of
+  the arithmetic is no longer "undefined".
+
+  There is also ``__attribute__((no_wraps))`` which can be added to types or
+  variable declarations. Types or variables with this attribute may be
+  instrumented by overflow sanitizers, if enabled. Note that this matches the
+  default behavior of integer types. So, in most cases, ``no_wraps`` serves
+  purely as an annotation to readers of code that a type or variable really
+  shouldn't wrap-around. ``__attribute__((no_wraps))`` has the most function
+  when paired with `Sanitizer Special Case Lists (SSCL)
+  `_.
+
+  These attributes are only valid for C, as there are built-in language
+  alternatives for other languages.
+
 Improvements to Clang's diagnostics
 ---
 
diff --git a/clang/docs/SanitizerSpecialCaseList.rst 
b/clang/docs/SanitizerSpecialCaseList.rst
index 96a7b2fba4ae43..10462643b69c7f 100644
--- a/clang/docs/SanitizerSpecialCaseList.rst
+++ b/clang/docs/SanitizerSpecialCaseList.rst
@@ -67,9 +67,11 @@ types specified within an ignorelist.
 int a = 2147483647; // INT_MAX
 ++a;// Normally, an overflow with 
-fsanitize=signed-integer-overflow
   }
+
   $ cat ignorelist.txt
   [signed-integer-overflow]
   type:int
+
   $ clang -fsanitize=signed-integer-overflow 
-fsanitize-ignorelist=ignorelist.txt foo.c ; ./a.out
   # no signed-integer-overflow error
 
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 466c65a9685ad3..4472c941ed5c79 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -4142,6 +4142,12 @@ class BinaryOperator : public Expr {
 return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
   }
 
+  /// Does one of the subexpressions have the wraps attribute?
+  bool hasWrappingOperand(const ASTContext &Ctx) const;
+
+  /// How about the no_wraps attribute?
+  bool hasNonWrappingOperand(const ASTContext &Ctx) const;
+
 protected:
   BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
  QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 1bcc7ee0b70dee..c7f368c0193664 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/

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

2024-11-06 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-06 Thread Justin Stitt via cfe-commits


@@ -4142,6 +4142,12 @@ class BinaryOperator : public Expr {
 return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
   }
 
+  /// Does one of the subexpressions have the wraps attribute?
+  bool hasWrappingOperand(const ASTContext &Ctx) const;
+
+  /// How about the no_wraps attribute?
+  bool hasNonWrappingOperand(const ASTContext &Ctx) const;

JustinStitt wrote:

Oops, nice catch. Fixed in 
https://github.com/llvm/llvm-project/pull/115094/commits/3e3ad8aa2dacdd0ea209e6540582b25caf3b9b00

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-06 Thread Justin Stitt via cfe-commits

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

>From f58e6481650f8cda6089b2a0637c94596a45370e Mon Sep 17 00:00:00 2001
From: Justin Stitt 
Date: Tue, 5 Mar 2024 03:14:49 +
Subject: [PATCH 1/5] add wraps, no_wraps attributes

---
 clang/docs/ReleaseNotes.rst   |  20 
 clang/docs/SanitizerSpecialCaseList.rst   |   2 +
 clang/include/clang/AST/Expr.h|   6 ++
 clang/include/clang/AST/Type.h|   3 +
 clang/include/clang/Basic/Attr.td |  15 +++
 clang/include/clang/Basic/AttrDocs.td | 100 ++
 clang/include/clang/Basic/DiagnosticGroups.td |   6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   7 ++
 clang/lib/AST/Expr.cpp|  20 
 clang/lib/AST/ExprConstant.cpp|   4 +-
 clang/lib/AST/Type.cpp|   9 ++
 clang/lib/AST/TypePrinter.cpp |   6 ++
 clang/lib/CodeGen/CGExprScalar.cpp|  48 ++---
 clang/lib/Sema/Sema.cpp   |   3 +
 clang/lib/Sema/SemaChecking.cpp   |  35 +-
 clang/lib/Sema/SemaDecl.cpp   |   2 +-
 clang/lib/Sema/SemaDeclAttr.cpp   |  16 ++-
 clang/lib/Sema/SemaType.cpp   |  25 +
 clang/test/CodeGen/integer-overflow.c |  66 
 clang/test/CodeGen/unsigned-overflow.c|  63 +--
 clang/test/CodeGen/wraps-attribute-scl.test   |  78 ++
 ...a-attribute-supported-attributes-list.test |   2 +
 clang/test/Sema/attr-wraps.c  |  48 +
 23 files changed, 556 insertions(+), 28 deletions(-)
 create mode 100644 clang/test/CodeGen/wraps-attribute-scl.test
 create mode 100644 clang/test/Sema/attr-wraps.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index dc45202f6b2e86..5457d802d820f3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -386,6 +386,26 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow behavior for that expression as having
+  two's complement wrap-around. These expressions will not be instrumented by
+  overflow sanitizers nor will they cause integer overflow warnings. They also
+  cannot be optimized away by some eager UB optimizations as the behavior of
+  the arithmetic is no longer "undefined".
+
+  There is also ``__attribute__((no_wraps))`` which can be added to types or
+  variable declarations. Types or variables with this attribute may be
+  instrumented by overflow sanitizers, if enabled. Note that this matches the
+  default behavior of integer types. So, in most cases, ``no_wraps`` serves
+  purely as an annotation to readers of code that a type or variable really
+  shouldn't wrap-around. ``__attribute__((no_wraps))`` has the most function
+  when paired with `Sanitizer Special Case Lists (SSCL)
+  `_.
+
+  These attributes are only valid for C, as there are built-in language
+  alternatives for other languages.
+
 Improvements to Clang's diagnostics
 ---
 
diff --git a/clang/docs/SanitizerSpecialCaseList.rst 
b/clang/docs/SanitizerSpecialCaseList.rst
index 96a7b2fba4ae43..10462643b69c7f 100644
--- a/clang/docs/SanitizerSpecialCaseList.rst
+++ b/clang/docs/SanitizerSpecialCaseList.rst
@@ -67,9 +67,11 @@ types specified within an ignorelist.
 int a = 2147483647; // INT_MAX
 ++a;// Normally, an overflow with 
-fsanitize=signed-integer-overflow
   }
+
   $ cat ignorelist.txt
   [signed-integer-overflow]
   type:int
+
   $ clang -fsanitize=signed-integer-overflow 
-fsanitize-ignorelist=ignorelist.txt foo.c ; ./a.out
   # no signed-integer-overflow error
 
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 466c65a9685ad3..4472c941ed5c79 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -4142,6 +4142,12 @@ class BinaryOperator : public Expr {
 return getFPFeaturesInEffect(LO).getAllowFEnvAccess();
   }
 
+  /// Does one of the subexpressions have the wraps attribute?
+  bool hasWrappingOperand(const ASTContext &Ctx) const;
+
+  /// How about the no_wraps attribute?
+  bool hasNonWrappingOperand(const ASTContext &Ctx) const;
+
 protected:
   BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc,
  QualType ResTy, ExprValueKind VK, ExprObjectKind OK,
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 1bcc7ee0b70dee..c7f368c0193664 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/

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

2024-11-06 Thread Justin Stitt via cfe-commits

https://github.com/JustinStitt edited 
https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-06 Thread Justin Stitt via cfe-commits


@@ -67,9 +67,11 @@ types specified within an ignorelist.
 int a = 2147483647; // INT_MAX
 ++a;// Normally, an overflow with 
-fsanitize=signed-integer-overflow
   }
+

JustinStitt wrote:

The wraps docs reference the SSCL docs and I fixed some whitespace in the 
example to make it more readable.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-05 Thread Vitaly Buka via cfe-commits


@@ -67,9 +67,11 @@ types specified within an ignorelist.
 int a = 2147483647; // INT_MAX
 ++a;// Normally, an overflow with 
-fsanitize=signed-integer-overflow
   }
+

vitalybuka wrote:

Please do unrelated fixes in separate PRs.

https://github.com/llvm/llvm-project/pull/115094
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2024-11-05 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff c949500d519085a4e5b93928b14ca766a353ad73 
bd63565b43c17f16b9c2a79143368e7ef607f14c --extensions cpp,h,c -- 
clang/test/Sema/attr-wraps.c clang/include/clang/AST/Expr.h 
clang/include/clang/AST/Type.h clang/lib/AST/Expr.cpp 
clang/lib/AST/ExprConstant.cpp clang/lib/AST/Type.cpp 
clang/lib/AST/TypePrinter.cpp clang/lib/CodeGen/CGExprScalar.cpp 
clang/lib/Sema/Sema.cpp clang/lib/Sema/SemaChecking.cpp 
clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaDeclAttr.cpp 
clang/lib/Sema/SemaType.cpp clang/test/CodeGen/integer-overflow.c 
clang/test/CodeGen/unsigned-overflow.c
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 7de87039cc..5a3655ec8f 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -4866,7 +4866,6 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, 
Expr *lhs, Expr *rhs,
 setType(Ctx.getAttributedType(attr::Wraps, getType(), getType()));
   if (hasNonWrappingOperand(Ctx))
 setType(Ctx.getAttributedType(attr::NoWraps, getType(), getType()));
-
 }
 
 BinaryOperator::BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs,
@@ -4889,7 +4888,6 @@ BinaryOperator::BinaryOperator(const ASTContext &Ctx, 
Expr *lhs, Expr *rhs,
 setType(Ctx.getAttributedType(attr::Wraps, getType(), getType()));
   if (hasNonWrappingOperand(Ctx))
 setType(Ctx.getAttributedType(attr::NoWraps, getType(), getType()));
-
 }
 
 BinaryOperator *BinaryOperator::CreateEmpty(const ASTContext &C,
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp 
b/clang/lib/CodeGen/CGExprScalar.cpp
index a4efb0cd5d..4f0365ba80 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -3033,8 +3033,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const 
UnaryOperator *E, LValue LV,
   value = EmitIncDecConsiderOverflowBehavior(E, value, isInc);
 } else if (E->canOverflow() && type->isUnsignedIntegerType() &&
CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
-   !Ops.hasWrappingOperand() &&
-   !excludeOverflowPattern &&
+   !Ops.hasWrappingOperand() && !excludeOverflowPattern &&
!CGF.getContext().isTypeIgnoredBySanitizer(
SanitizerKind::UnsignedIntegerOverflow, E->getType())) {
   value = EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a09519fd62..c29a5fb6a6 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -24,13 +24,14 @@
 #include "clang/AST/EvaluatedExprVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
-#include "clang/AST/NonTrivialTypeVisitor.h"
 #include "clang/AST/MangleNumberingContext.h"
+#include "clang/AST/NonTrivialTypeVisitor.h"
 #include "clang/AST/Randstruct.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/HLSLRuntime.h"
+#include "clang/Basic/NoSanitizeList.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
@@ -56,7 +57,6 @@
 #include "clang/Sema/SemaSwift.h"
 #include "clang/Sema/SemaWasm.h"
 #include "clang/Sema/Template.h"
-#include "clang/Basic/NoSanitizeList.h"
 #include "llvm/ADT/STLForwardCompat.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
@@ -6715,9 +6715,10 @@ Sema::CheckTypedefForVariablyModifiedType(Scope *S, 
TypedefNameDecl *NewTD) {
   }
 }
 
-NamedDecl*
-Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC, TypedefNameDecl *NewTD,
-   LookupResult &Previous, bool &Redeclaration) {
+NamedDecl *Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC,
+  TypedefNameDecl *NewTD,
+  LookupResult &Previous,
+  bool &Redeclaration) {
   // Find the shadowed declaration before filtering for scope.
   NamedDecl *ShadowedDecl = getShadowedDeclaration(NewTD, Previous);
 
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 1f1c8a8dee..c48b947591 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -6961,7 +6961,6 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, 
const ParsedAttr &AL,
 handleWrapsAttr(S, D, AL, true);
 break;
 
-
   // Microsoft attributes:
   case ParsedAttr::AT_LayoutVersion:
 handleLayoutVersion(S, D, AL);
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 08e00879d6..1933ce56ba 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6543,7 +6543,7 @@ static void handleWrapsAttr(QualType &T

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

2024-11-05 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Justin Stitt (JustinStitt)


Changes

> [!NOTE]  
> Expansion of https://github.com/llvm/llvm-project/pull/86618, with a 
larger scope including `no_wraps` and 
[SSCL](https://clang.llvm.org/docs/SanitizerSpecialCaseList.html) integration. 
There's more background and review that is worth reading in #86618 as 
well.

Implement `__attribute__((wraps))` and `__attribute__((no_wraps))`. These 
attributes are used to annotate the expected wrap-around behavior for types, 
variables, struct members, or function parameters.

These attributes serve as convenient in-source annotations for the expected 
overflow behavior of code. In addition, these attributes also have functional 
changes when used alongside certain sanitizers or warnings.

The `signed-integer-overflow`, `unsigned-integer-overflow`, 
`implicit-signed-integer-truncation` and the 
`implicit-unsigned-integer-truncation` sanitizers have different behavior when 
interacting with the `wraps` attribute.

This is most useful for users that want to enable overflow or truncation 
sanitizers but also have some code they want to not be instrumented. Without 
this PR, they can only achieve translation unit level or at best function level 
granularity without changing arithmetic expressions directly. In an effort to 
not make basic arithmetic rely on wrappers like `__builtin_add_overflow()`, 
this PR introduces type and variable level granularity.

 Example
```c
void foo(int __attribute__((wraps)) A) {
  ++A; // No overflow/truncation sanitizers will instrument this code
}
```

 no_wraps

`no_wraps` is interesting because it reflects the default case for integer 
operations and the associated sanitizers. In the general case, `no_wraps` just 
serves as a friendly annotation to readers of code that something is really not 
supposed to wrap-around. The sanitizers will instrument them all the same as 
they would if this attribute was not present.

What makes `no_wraps` useful is when 
[SSCLs](https://clang.llvm.org/docs/SanitizerSpecialCaseList.html) are used 
alongside them. https://github.com/llvm/llvm-project/pull/107332 introduced 
type-filtering for the overflow and truncation sanitizers which can be 
overriden by `no_wraps` and `wraps`. To illustrate, let's look at another 
example:


```
[signed-integer-overflow]
type:*
```

```c
typedef int __attribute__((no_wraps)) non_wrapping_int;

void bar(int A, non_wrapping_int B) {
  ++A; // will not have instrumentation (ignored within the ignorelist)
  ++B; // will have instrumentation (ignored within ignorelist, but overridden 
by no_wraps)
}
```


### CC
@vitalybuka @kees @melver @bwendling 



---

Patch is 44.62 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/115094.diff


23 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+21) 
- (modified) clang/docs/SanitizerSpecialCaseList.rst (+2) 
- (modified) clang/include/clang/AST/Expr.h (+6) 
- (modified) clang/include/clang/AST/Type.h (+3) 
- (modified) clang/include/clang/Basic/Attr.td (+15) 
- (modified) clang/include/clang/Basic/AttrDocs.td (+100) 
- (modified) clang/include/clang/Basic/DiagnosticGroups.td (+6) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+7) 
- (modified) clang/lib/AST/Expr.cpp (+20) 
- (modified) clang/lib/AST/ExprConstant.cpp (+2-2) 
- (modified) clang/lib/AST/Type.cpp (+9) 
- (modified) clang/lib/AST/TypePrinter.cpp (+6) 
- (modified) clang/lib/CodeGen/CGExprScalar.cpp (+35-13) 
- (modified) clang/lib/Sema/Sema.cpp (+3) 
- (modified) clang/lib/Sema/SemaChecking.cpp (+32-3) 
- (modified) clang/lib/Sema/SemaDecl.cpp (+1-1) 
- (modified) clang/lib/Sema/SemaDeclAttr.cpp (+15-1) 
- (modified) clang/lib/Sema/SemaType.cpp (+25) 
- (modified) clang/test/CodeGen/integer-overflow.c (+66) 
- (modified) clang/test/CodeGen/unsigned-overflow.c (+55-8) 
- (added) clang/test/CodeGen/wraps-attribute-scl.test (+78) 
- (modified) clang/test/Misc/pragma-attribute-supported-attributes-list.test 
(+2) 
- (added) clang/test/Sema/attr-wraps.c (+48) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index dc45202f6b2e86..c18410e6544081 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -386,6 +386,27 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow behavior for that expression as having
+  two's complement wrap-around. These expressions will not be instrumented by
+  overflow sanitizers nor will they cause integer overflow warnings. They also
+  cannot be optimized away by some eager UB optimizations as the behavior of
+  the arithmetic 

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

2024-11-05 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: Justin Stitt (JustinStitt)


Changes

> [!NOTE]  
> Expansion of https://github.com/llvm/llvm-project/pull/86618, with a 
larger scope including `no_wraps` and 
[SSCL](https://clang.llvm.org/docs/SanitizerSpecialCaseList.html) integration. 
There's more background and review that is worth reading in #86618 as 
well.

Implement `__attribute__((wraps))` and `__attribute__((no_wraps))`. These 
attributes are used to annotate the expected wrap-around behavior for types, 
variables, struct members, or function parameters.

These attributes serve as convenient in-source annotations for the expected 
overflow behavior of code. In addition, these attributes also have functional 
changes when used alongside certain sanitizers or warnings.

The `signed-integer-overflow`, `unsigned-integer-overflow`, 
`implicit-signed-integer-truncation` and the 
`implicit-unsigned-integer-truncation` sanitizers have different behavior when 
interacting with the `wraps` attribute.

This is most useful for users that want to enable overflow or truncation 
sanitizers but also have some code they want to not be instrumented. Without 
this PR, they can only achieve translation unit level or at best function level 
granularity without changing arithmetic expressions directly. In an effort to 
not make basic arithmetic rely on wrappers like `__builtin_add_overflow()`, 
this PR introduces type and variable level granularity.

 Example
```c
void foo(int __attribute__((wraps)) A) {
  ++A; // No overflow/truncation sanitizers will instrument this code
}
```

 no_wraps

`no_wraps` is interesting because it reflects the default case for integer 
operations and the associated sanitizers. In the general case, `no_wraps` just 
serves as a friendly annotation to readers of code that something is really not 
supposed to wrap-around. The sanitizers will instrument them all the same as 
they would if this attribute was not present.

What makes `no_wraps` useful is when 
[SSCLs](https://clang.llvm.org/docs/SanitizerSpecialCaseList.html) are used 
alongside them. https://github.com/llvm/llvm-project/pull/107332 introduced 
type-filtering for the overflow and truncation sanitizers which can be 
overriden by `no_wraps` and `wraps`. To illustrate, let's look at another 
example:


```
[signed-integer-overflow]
type:*
```

```c
typedef int __attribute__((no_wraps)) non_wrapping_int;

void bar(int A, non_wrapping_int B) {
  ++A; // will not have instrumentation (ignored within the ignorelist)
  ++B; // will have instrumentation (ignored within ignorelist, but overridden 
by no_wraps)
}
```


### CC
@vitalybuka @kees @melver @bwendling 



---

Patch is 44.62 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/115094.diff


23 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+21) 
- (modified) clang/docs/SanitizerSpecialCaseList.rst (+2) 
- (modified) clang/include/clang/AST/Expr.h (+6) 
- (modified) clang/include/clang/AST/Type.h (+3) 
- (modified) clang/include/clang/Basic/Attr.td (+15) 
- (modified) clang/include/clang/Basic/AttrDocs.td (+100) 
- (modified) clang/include/clang/Basic/DiagnosticGroups.td (+6) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+7) 
- (modified) clang/lib/AST/Expr.cpp (+20) 
- (modified) clang/lib/AST/ExprConstant.cpp (+2-2) 
- (modified) clang/lib/AST/Type.cpp (+9) 
- (modified) clang/lib/AST/TypePrinter.cpp (+6) 
- (modified) clang/lib/CodeGen/CGExprScalar.cpp (+35-13) 
- (modified) clang/lib/Sema/Sema.cpp (+3) 
- (modified) clang/lib/Sema/SemaChecking.cpp (+32-3) 
- (modified) clang/lib/Sema/SemaDecl.cpp (+1-1) 
- (modified) clang/lib/Sema/SemaDeclAttr.cpp (+15-1) 
- (modified) clang/lib/Sema/SemaType.cpp (+25) 
- (modified) clang/test/CodeGen/integer-overflow.c (+66) 
- (modified) clang/test/CodeGen/unsigned-overflow.c (+55-8) 
- (added) clang/test/CodeGen/wraps-attribute-scl.test (+78) 
- (modified) clang/test/Misc/pragma-attribute-supported-attributes-list.test 
(+2) 
- (added) clang/test/Sema/attr-wraps.c (+48) 


``diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index dc45202f6b2e86..c18410e6544081 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -386,6 +386,27 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow behavior for that expression as having
+  two's complement wrap-around. These expressions will not be instrumented by
+  overflow sanitizers nor will they cause integer overflow warnings. They also
+  cannot be optimized away by some eager UB optimizations as the behavior of
+  the ari

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

2024-11-05 Thread Justin Stitt via cfe-commits

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

> [!NOTE]  
> Expansion of https://github.com/llvm/llvm-project/pull/86618, with a larger 
> scope including `no_wraps` and 
> [SSCL](https://clang.llvm.org/docs/SanitizerSpecialCaseList.html) 
> integration. There's more background and review that is worth reading in 
> #86618 as well.

Implement `__attribute__((wraps))` and `__attribute__((no_wraps))`. These 
attributes are used to annotate the expected wrap-around behavior for types, 
variables, struct members, or function parameters.

These attributes serve as convenient in-source annotations for the expected 
overflow behavior of code. In addition, these attributes also have functional 
changes when used alongside certain sanitizers or warnings.

The `signed-integer-overflow`, `unsigned-integer-overflow`, 
`implicit-signed-integer-truncation` and the 
`implicit-unsigned-integer-truncation` sanitizers have different behavior when 
interacting with the `wraps` attribute.

This is most useful for users that want to enable overflow or truncation 
sanitizers but also have some code they want to not be instrumented. Without 
this PR, they can only achieve translation unit level or at best function level 
granularity without changing arithmetic expressions directly. In an effort to 
not make basic arithmetic rely on wrappers like `__builtin_add_overflow()`, 
this PR introduces type and variable level granularity.

 Example
```c
void foo(int __attribute__((wraps)) A) {
  ++A; // No overflow/truncation sanitizers will instrument this code
}
```

 no_wraps

`no_wraps` is interesting because it reflects the default case for integer 
operations and the associated sanitizers. In the general case, `no_wraps` just 
serves as a friendly annotation to readers of code that something is really not 
supposed to wrap-around. The sanitizers will instrument them all the same as 
they would if this attribute was not present.

What makes `no_wraps` useful is when 
[SSCLs](https://clang.llvm.org/docs/SanitizerSpecialCaseList.html) are used 
alongside them. https://github.com/llvm/llvm-project/pull/107332 introduced 
type-filtering for the overflow and truncation sanitizers which can be 
overriden by `no_wraps` and `wraps`. To illustrate, let's look at another 
example:


```
[signed-integer-overflow]
type:*
```

```c
typedef int __attribute__((no_wraps)) non_wrapping_int;

void bar(int A, non_wrapping_int B) {
  ++A; // will not have instrumentation (ignored within the ignorelist)
  ++B; // will have instrumentation (ignored within ignorelist, but overridden 
by no_wraps)
}
```


### CC
@vitalybuka @kees @melver @bwendling 



>From bd63565b43c17f16b9c2a79143368e7ef607f14c Mon Sep 17 00:00:00 2001
From: Justin Stitt 
Date: Tue, 5 Mar 2024 03:14:49 +
Subject: [PATCH] add wraps, no_wraps attributes

---
 clang/docs/ReleaseNotes.rst   |  21 
 clang/docs/SanitizerSpecialCaseList.rst   |   2 +
 clang/include/clang/AST/Expr.h|   6 ++
 clang/include/clang/AST/Type.h|   3 +
 clang/include/clang/Basic/Attr.td |  15 +++
 clang/include/clang/Basic/AttrDocs.td | 100 ++
 clang/include/clang/Basic/DiagnosticGroups.td |   6 ++
 .../clang/Basic/DiagnosticSemaKinds.td|   7 ++
 clang/lib/AST/Expr.cpp|  20 
 clang/lib/AST/ExprConstant.cpp|   4 +-
 clang/lib/AST/Type.cpp|   9 ++
 clang/lib/AST/TypePrinter.cpp |   6 ++
 clang/lib/CodeGen/CGExprScalar.cpp|  48 ++---
 clang/lib/Sema/Sema.cpp   |   3 +
 clang/lib/Sema/SemaChecking.cpp   |  35 +-
 clang/lib/Sema/SemaDecl.cpp   |   2 +-
 clang/lib/Sema/SemaDeclAttr.cpp   |  16 ++-
 clang/lib/Sema/SemaType.cpp   |  25 +
 clang/test/CodeGen/integer-overflow.c |  66 
 clang/test/CodeGen/unsigned-overflow.c|  63 +--
 clang/test/CodeGen/wraps-attribute-scl.test   |  78 ++
 ...a-attribute-supported-attributes-list.test |   2 +
 clang/test/Sema/attr-wraps.c  |  48 +
 23 files changed, 557 insertions(+), 28 deletions(-)
 create mode 100644 clang/test/CodeGen/wraps-attribute-scl.test
 create mode 100644 clang/test/Sema/attr-wraps.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index dc45202f6b2e86..c18410e6544081 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -386,6 +386,27 @@ Attribute Changes in Clang
 - Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
   ``[[gsl::Pointer]]`` to STL explicit template specialization decls. 
(#GH109442)
 
+- Introduced ``__attribute__((wraps))`` which can be added to type or variable
+  declarations. Using an attributed type or variable in an arithmetic
+  expression will define the overflow