While Linux's use of -fno-strict-overflow means that all arithmetic
operations have a defined behavior (2's-complement wrapping), there
isn't a way to unambiguously specify if a given variable was designed
or intended to wrap around by the author.

Introduce explicit trapping and wrapping types for all bit widths
including architecture word length (i.e. "long"), signed and unsigned,
for use going forward for unambiguous arithmetic, now available via
Clang 23+'s Overflow Behavior Types[1] (CONFIG_OVERFLOW_BEHAVIOR_TYPES=y).

Bike shedding time! How should these be named? We already have the short
bit width types, named as: {u,s}{8,16,32,64}. We need to construct new
type names that also indicate their overflow behavior: "trapping" or
"wrapping". And we need to capture the "architectural word" length type
too (i.e. what "unsigned long" or "size_t" captures).

Whole word addition:
- Pro: Unambiguous
- Con: Long. E.g. suffixed "u16_trap", or prefixed "wrap_u16"

Single letter addition, "t" for "trap" and "w" for "wrap":
- At the end: but "u8t" looks like the "t" is "type", like "uint8_t".
- At the front: but "wu8" looks like the "w" is "wide", like "wchar_t".

Current straw-man proposal is single letter suffix because it vaguely
felt like the least bad of all choices, and they should be short or
everyone will just continue to type "int". :)

Link: https://clang.llvm.org/docs/OverflowBehaviorTypes.html [1]
Signed-off-by: Kees Cook <[email protected]>
---
Cc: Justin Stitt <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Miguel Ojeda <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Mark Rutland <[email protected]>
Cc: "Matthew Wilcox (Oracle)" <[email protected]>
Cc: Suren Baghdasaryan <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Finn Thain <[email protected]>
Cc: Geert Uytterhoeven <[email protected]>
Cc: "Thomas Weißschuh" <[email protected]>
Cc: <[email protected]>
---
 include/linux/types.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/include/linux/types.h b/include/linux/types.h
index 7e71d260763c..786eb2c9775f 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -94,6 +94,30 @@ typedef unsigned int         uint;
 typedef unsigned long          ulong;
 typedef unsigned long long     ullong;
 
+/* Trapping types. */
+typedef u8 __ob_trap           u8t;
+typedef u16 __ob_trap          u16t;
+typedef u32 __ob_trap          u32t;
+typedef u64 __ob_trap          u64t;
+typedef unsigned long __ob_trap        ulongt;
+typedef s8 __ob_trap           s8t;
+typedef s16 __ob_trap          s16t;
+typedef s32 __ob_trap          s32t;
+typedef s64 __ob_trap          s64t;
+typedef signed long __ob_trap  slongt;
+
+/* Wrapping types. */
+typedef u8 __ob_wrap           u8w;
+typedef u16 __ob_wrap          u16w;
+typedef u32 __ob_wrap          u32w;
+typedef u64 __ob_wrap          u64w;
+typedef unsigned long __ob_wrap        ulongw;
+typedef s8 __ob_wrap           s8w;
+typedef s16 __ob_wrap          s16w;
+typedef s32 __ob_wrap          s32w;
+typedef s64 __ob_wrap          s64w;
+typedef signed long __ob_wrap  slongw;
+
 #ifndef __BIT_TYPES_DEFINED__
 #define __BIT_TYPES_DEFINED__
 
-- 
2.34.1


Reply via email to