@@ -30,8 +30,8 @@ There are two syntax options for specifying overflow behavior:
30
30
31
31
.. code-block :: c++
32
32
33
- __wrap // equivalent to __attribute__((overflow_behavior(wrap)))
34
- __no_wrap // equivalent to __attribute__((overflow_behavior(no_wrap )))
33
+ __ob_wrap // equivalent to __attribute__((overflow_behavior(wrap)))
34
+ __ob_trap // equivalent to __attribute__((overflow_behavior(trap )))
35
35
36
36
Where ``behavior `` can be one of the following:
37
37
@@ -44,7 +44,7 @@ Where ``behavior`` can be one of the following:
44
44
``implicit-unsigned-integer-truncation ``) are suppressed for the attributed
45
45
type.
46
46
47
- * ``no_wrap ``: Specifies that arithmetic operations on the integer type should
47
+ * ``trap ``: Specifies that arithmetic operations on the integer type should
48
48
be checked for overflow. When using the ``signed-integer-overflow `` sanitizer
49
49
or when using ``-ftrapv `` alongside a signed type, this is the default
50
50
behavior. Using this, one may enforce overflow checks for a type even when
@@ -65,7 +65,7 @@ Here are examples using both syntax options:
65
65
66
66
.. code-block :: c++
67
67
68
- typedef unsigned int __attribute__((overflow_behavior(no_wrap ))) non_wrapping_uint;
68
+ typedef unsigned int __attribute__((overflow_behavior(trap ))) non_wrapping_uint;
69
69
70
70
non_wrapping_uint add_one(non_wrapping_uint a) {
71
71
return a + 1; // Overflow is checked for this operation.
@@ -75,7 +75,7 @@ Here are examples using both syntax options:
75
75
76
76
.. code-block :: c++
77
77
78
- typedef unsigned int __no_wrap non_wrapping_uint;
78
+ typedef unsigned int __trap non_wrapping_uint;
79
79
80
80
non_wrapping_uint add_one(non_wrapping_uint a) {
81
81
return a + 1; // Overflow is checked for this operation.
@@ -121,10 +121,10 @@ variety of scenarios is detailed below.
121
121
122
122
.. code-block :: c++
123
123
124
- typedef char __no_wrap no_wrap_char ;
125
- no_wrap_char c;
124
+ typedef char __trap trap_char ;
125
+ trap_char c;
126
126
unsigned long ul;
127
- auto result = c + ul; // result is no_wrap_char
127
+ auto result = c + ul; // result is trap_char
128
128
129
129
* **Two OBTs of the Same Kind **: When an operation involves two OBTs of the
130
130
same kind (e.g., both ``wrap ``), the result will have the larger of the two
@@ -140,11 +140,11 @@ variety of scenarios is detailed below.
140
140
auto result = a + b; // result is u16_wrap
141
141
142
142
* **Two OBTs of Different Kinds **: In an operation between a ``wrap `` and a
143
- ``no_wrap `` type, a ``no_wrap `` type is always produced. Clang will bias the
144
- ``no_wrap `` type as converting from ``wrap `` to ``no_wrap `` is not as
145
- troubling as converting from ``no_wrap `` to ``wrap ``, in most cases.
143
+ ``trap `` type, a ``trap `` type is always produced. Clang will bias the
144
+ ``trap `` type as converting from ``wrap `` to ``trap `` is not as
145
+ troubling as converting from ``trap `` to ``wrap ``, in most cases.
146
146
Therefore, the resulting type matches the bit-width, sign and behavior of the
147
- ``no_wrap `` type. It is recommended to avoid such operations, as Clang may
147
+ ``trap `` type. It is recommended to avoid such operations, as Clang may
148
148
emit a warning for these cases in the future.
149
149
150
150
@@ -156,10 +156,10 @@ variety of scenarios is detailed below.
156
156
- Result Type
157
157
* - OBT + Standard Integer
158
158
- OBT type (preserves overflow behavior, sign, and bit-width)
159
- * - Same Kind OBTs (both ``wrap `` or both ``no_wrap ``)
159
+ * - Same Kind OBTs (both ``wrap `` or both ``trap ``)
160
160
- Larger bit-width; unsigned favored if same width
161
- * - Different Kind OBTs (``wrap `` + ``no_wrap ``)
162
- - ``no_wrap `` type (matches ``no_wrap `` operand's characteristics)
161
+ * - Different Kind OBTs (``wrap `` + ``trap ``)
162
+ - ``trap `` type (matches ``trap `` operand's characteristics)
163
163
164
164
Following traditional C promotion rules for integer types often results in
165
165
modified bit boundaries for types. Since overflow behavior types aim to make
@@ -173,13 +173,13 @@ promotion rules:
173
173
174
174
.. code-block :: c++
175
175
176
- unsigned short __no_wrap a = 0; // u16 __no_wrap
176
+ unsigned short __trap a = 0; // u16 __trap
177
177
178
178
// Normally, arithmetic that is less-than-int is promoted to at least int.
179
179
// Following traditional C promotion rules: u16 + s32 results in s32
180
- // However, since `a ` is an OBT, our special promotion rules apply: u16 __no_wrap + s32 results in u16 __no_wrap
180
+ // However, since `a ` is an OBT, our special promotion rules apply: u16 __trap + s32 results in u16 __trap
181
181
182
- a + 1; // result is short __no_wrap
182
+ a + 1; // result is short __trap
183
183
184
184
Conversion Semantics
185
185
====================
@@ -207,8 +207,8 @@ the **destination type**:
207
207
// Examples of constant conversion behavior
208
208
short x1 = (int __wrap)100000; // Warning: truncation to standard type
209
209
short __wrap x2 = (int)100000; // No warning: wrapping destination (also no UBSan truncation warning)
210
- short __no_wrap x3 = (int)100000; // Warning: truncation with overflow check
211
- short x4 = (int __no_wrap )100000; // Warning: truncation to standard type
210
+ short __trap x3 = (int)100000; // Warning: truncation with overflow check
211
+ short x4 = (int __trap )100000; // Warning: truncation to standard type
212
212
213
213
This rule ensures that explicit use of wrapping types suppresses warnings
214
214
only when the destination is intended to wrap, while preserving warnings
@@ -237,9 +237,9 @@ is always used - just like with traditional integer types.
237
237
.. code-block :: c++
238
238
239
239
long __wrap x = __LONG_MAX__;
240
- int __no_wrap a = x; // x converted to int __no_wrap
240
+ int __trap a = x; // x converted to int __trap
241
241
242
- For the purposes of truncation warnings from UBSAN or ``-Wconversion ``, the
242
+ For the purposes of truncation warnings from UBSan or ``-Wconversion ``, the
243
243
left-hand side's overflow behavior determines the instrumentation and
244
244
reporting. For example, the code above would cause a ``-Wshorten-64-to-32 ``
245
245
warning. Swapping the overflow behavior kinds in the above example would not
@@ -266,7 +266,7 @@ conversion, the behavior depends on the **destination type**:
266
266
// C++ narrowing conversion behavior
267
267
constexpr short __wrap x1 = {(int)100000}; // OK: wrapping destination
268
268
constexpr short x2 = {(int)100000}; // Error: standard destination
269
- constexpr short __no_wrap x3 = {(int)100000}; // Error: non-wrapping destination
269
+ constexpr short __trap x3 = {(int)100000}; // Error: non-wrapping destination
270
270
271
271
This allows ``wrap `` types to be used seamlessly in ``constexpr `` contexts
272
272
where truncation is intentional and expected.
@@ -298,7 +298,7 @@ type of an OBT parameter is not enough to precisely pick an overload candidate.
298
298
299
299
.. code-block :: c++
300
300
301
- void foo(int __no_wrap a);
301
+ void foo(int __trap a);
302
302
void foo(short a);
303
303
304
304
void bar(int a) {
@@ -311,11 +311,11 @@ candidates are not implicitly convertible.
311
311
312
312
.. code-block :: c++
313
313
314
- void foo(int __no_wrap a);
314
+ void foo(int __trap a);
315
315
void foo(char *a);
316
316
317
317
void bar(int a) {
318
- foo(a); // picks foo(__no_wrap int)
318
+ foo(a); // picks foo(__trap int)
319
319
}
320
320
321
321
@@ -324,7 +324,7 @@ certain contexts.
324
324
325
325
.. code-block :: c++
326
326
327
- void foo(int __no_wrap a);
327
+ void foo(int __trap a);
328
328
void foo(int __wrap a);
329
329
330
330
void bar(int a) {
@@ -382,8 +382,8 @@ specialization purposes, enabling precise type-based template selection.
382
382
};
383
383
384
384
template<>
385
- struct TypeProcessor<int __no_wrap > {
386
- static constexpr int value = 3; // __no_wrap int specialization
385
+ struct TypeProcessor<int __trap > {
386
+ static constexpr int value = 3; // __trap int specialization
387
387
};
388
388
389
389
When no exact template specialization exists for an OBT, it falls back to the
@@ -413,15 +413,15 @@ global flags. The following table summarizes the interactions:
413
413
- Wraps
414
414
- No report
415
415
- Overrides SSCL
416
- * - ``overflow_behavior(no_wrap ) ``
416
+ * - ``overflow_behavior(trap ) ``
417
417
- Traps
418
418
- Traps
419
419
- Traps
420
420
- Reports
421
421
- Overrides SSCL
422
422
423
423
It is important to note the distinction between signed and unsigned types. For
424
- unsigned integers, which wrap on overflow by default, ``overflow_behavior(no_wrap ) ``
424
+ unsigned integers, which wrap on overflow by default, ``overflow_behavior(trap ) ``
425
425
is particularly useful for enabling overflow checks. For signed integers, whose
426
426
overflow behavior is undefined by default, ``overflow_behavior(wrap) `` provides
427
427
a guaranteed wrapping behavior.
@@ -493,11 +493,11 @@ loss of the specified overflow behavior. This is the main warning in the
493
493
// [-Wimplicit-overflow-behavior-conversion]
494
494
}
495
495
496
- Here's another example showing function parameter conversion with a ``no_wrap `` type:
496
+ Here's another example showing function parameter conversion with a ``trap `` type:
497
497
498
498
.. code-block :: c++
499
499
500
- typedef int __no_wrap safe_int;
500
+ typedef int __trap safe_int;
501
501
502
502
void bar(int x); // Function expects standard int
503
503
@@ -514,7 +514,7 @@ integer type.
514
514
.. code-block :: c++
515
515
516
516
typedef int __wrap wrapping_int;
517
- typedef int __no_wrap safe_int;
517
+ typedef int __trap safe_int;
518
518
519
519
void some_function() {
520
520
wrapping_int w = 1;
@@ -589,7 +589,7 @@ types when passed to any varargs function.
589
589
#include <cstdio>
590
590
591
591
typedef int __wrap wrap_int;
592
- typedef unsigned int __no_wrap nowrap_uint;
592
+ typedef unsigned int __trap nowrap_uint;
593
593
594
594
void example() {
595
595
wrap_int wi = 42;
@@ -609,19 +609,17 @@ The format string checker uses the underlying type to determine compatibility,
609
609
so ``int __wrap `` is fully compatible with
610
610
``%d ``, ``%i ``, ``%x ``, etc., just like a regular ``int `` would be.
611
611
612
- -Woverflow-behavior-attribute-ignored
613
- -------------------------------------
612
+ Using With Non-Integer Types
613
+ ----------------------------
614
614
615
- This warning is issued when attempting to create an overflow behavior type from
615
+ An error is issued when attempting to create an overflow behavior type from
616
616
a non-integer type.
617
617
618
618
.. code-block :: c++
619
619
620
620
typedef float __attribute__((overflow_behavior(wrap))) wrapping_float;
621
- // warning: 'overflow_behavior' attribute only applies to integer types;
622
- // attribute is ignored [-Woverflow-behavior-attribute-ignored]
621
+ // error: 'overflow_behavior' attribute cannot be applied to non-integer type 'float'
623
622
624
623
typedef struct S { int i; } __attribute__((overflow_behavior(wrap))) S_t;
625
- // warning: 'overflow_behavior' attribute only applies to integer types;
626
- // attribute is ignored [-Woverflow-behavior-attribute-ignored]
624
+ // error: 'overflow_behavior' attribute cannot be applied to non-integer type 'struct S'
627
625
0 commit comments