Skip to content

Commit 373d622

Browse files
committed
rename no_wrap to trap, use __ob prefix
For keywords, use __ob prefix (__ob_wrap, __ob_trap). Rename no_wrap to trap everywhere. Some warnings have been changed to errors. Transition to single-specifier guarantees, use pre-existing specifier diags Drop usage of OverflowBehaviorSpelling enum, it is now obsolete as we are using BadSpecifier() to handle specifier collisions. Signed-off-by: Justin Stitt <[email protected]>
1 parent 0bee82e commit 373d622

36 files changed

+472
-450
lines changed

clang/docs/OverflowBehaviorTypes.rst

Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ There are two syntax options for specifying overflow behavior:
3030

3131
.. code-block:: c++
3232

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)))
3535

3636
Where ``behavior`` can be one of the following:
3737

@@ -44,7 +44,7 @@ Where ``behavior`` can be one of the following:
4444
``implicit-unsigned-integer-truncation``) are suppressed for the attributed
4545
type.
4646

47-
* ``no_wrap``: Specifies that arithmetic operations on the integer type should
47+
* ``trap``: Specifies that arithmetic operations on the integer type should
4848
be checked for overflow. When using the ``signed-integer-overflow`` sanitizer
4949
or when using ``-ftrapv`` alongside a signed type, this is the default
5050
behavior. Using this, one may enforce overflow checks for a type even when
@@ -65,7 +65,7 @@ Here are examples using both syntax options:
6565

6666
.. code-block:: c++
6767

68-
typedef unsigned int __attribute__((overflow_behavior(no_wrap))) non_wrapping_uint;
68+
typedef unsigned int __attribute__((overflow_behavior(trap))) non_wrapping_uint;
6969

7070
non_wrapping_uint add_one(non_wrapping_uint a) {
7171
return a + 1; // Overflow is checked for this operation.
@@ -75,7 +75,7 @@ Here are examples using both syntax options:
7575

7676
.. code-block:: c++
7777

78-
typedef unsigned int __no_wrap non_wrapping_uint;
78+
typedef unsigned int __trap non_wrapping_uint;
7979

8080
non_wrapping_uint add_one(non_wrapping_uint a) {
8181
return a + 1; // Overflow is checked for this operation.
@@ -121,10 +121,10 @@ variety of scenarios is detailed below.
121121

122122
.. code-block:: c++
123123

124-
typedef char __no_wrap no_wrap_char;
125-
no_wrap_char c;
124+
typedef char __trap trap_char;
125+
trap_char c;
126126
unsigned long ul;
127-
auto result = c + ul; // result is no_wrap_char
127+
auto result = c + ul; // result is trap_char
128128

129129
* **Two OBTs of the Same Kind**: When an operation involves two OBTs of the
130130
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.
140140
auto result = a + b; // result is u16_wrap
141141

142142
* **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.
146146
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
148148
emit a warning for these cases in the future.
149149

150150

@@ -156,10 +156,10 @@ variety of scenarios is detailed below.
156156
- Result Type
157157
* - OBT + Standard Integer
158158
- 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``)
160160
- 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)
163163

164164
Following traditional C promotion rules for integer types often results in
165165
modified bit boundaries for types. Since overflow behavior types aim to make
@@ -173,13 +173,13 @@ promotion rules:
173173

174174
.. code-block:: c++
175175

176-
unsigned short __no_wrap a = 0; // u16 __no_wrap
176+
unsigned short __trap a = 0; // u16 __trap
177177

178178
// Normally, arithmetic that is less-than-int is promoted to at least int.
179179
// 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
181181

182-
a + 1; // result is short __no_wrap
182+
a + 1; // result is short __trap
183183

184184
Conversion Semantics
185185
====================
@@ -207,8 +207,8 @@ the **destination type**:
207207
// Examples of constant conversion behavior
208208
short x1 = (int __wrap)100000; // Warning: truncation to standard type
209209
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
212212

213213
This rule ensures that explicit use of wrapping types suppresses warnings
214214
only when the destination is intended to wrap, while preserving warnings
@@ -237,9 +237,9 @@ is always used - just like with traditional integer types.
237237
.. code-block:: c++
238238

239239
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
241241

242-
For the purposes of truncation warnings from UBSAN or ``-Wconversion``, the
242+
For the purposes of truncation warnings from UBSan or ``-Wconversion``, the
243243
left-hand side's overflow behavior determines the instrumentation and
244244
reporting. For example, the code above would cause a ``-Wshorten-64-to-32``
245245
warning. Swapping the overflow behavior kinds in the above example would not
@@ -266,7 +266,7 @@ conversion, the behavior depends on the **destination type**:
266266
// C++ narrowing conversion behavior
267267
constexpr short __wrap x1 = {(int)100000}; // OK: wrapping destination
268268
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
270270

271271
This allows ``wrap`` types to be used seamlessly in ``constexpr`` contexts
272272
where truncation is intentional and expected.
@@ -298,7 +298,7 @@ type of an OBT parameter is not enough to precisely pick an overload candidate.
298298

299299
.. code-block:: c++
300300

301-
void foo(int __no_wrap a);
301+
void foo(int __trap a);
302302
void foo(short a);
303303

304304
void bar(int a) {
@@ -311,11 +311,11 @@ candidates are not implicitly convertible.
311311

312312
.. code-block:: c++
313313

314-
void foo(int __no_wrap a);
314+
void foo(int __trap a);
315315
void foo(char *a);
316316
317317
void bar(int a) {
318-
foo(a); // picks foo(__no_wrap int)
318+
foo(a); // picks foo(__trap int)
319319
}
320320

321321

@@ -324,7 +324,7 @@ certain contexts.
324324

325325
.. code-block:: c++
326326

327-
void foo(int __no_wrap a);
327+
void foo(int __trap a);
328328
void foo(int __wrap a);
329329

330330
void bar(int a) {
@@ -382,8 +382,8 @@ specialization purposes, enabling precise type-based template selection.
382382
};
383383

384384
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
387387
};
388388

389389
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:
413413
- Wraps
414414
- No report
415415
- Overrides SSCL
416-
* - ``overflow_behavior(no_wrap)``
416+
* - ``overflow_behavior(trap)``
417417
- Traps
418418
- Traps
419419
- Traps
420420
- Reports
421421
- Overrides SSCL
422422

423423
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)``
425425
is particularly useful for enabling overflow checks. For signed integers, whose
426426
overflow behavior is undefined by default, ``overflow_behavior(wrap)`` provides
427427
a guaranteed wrapping behavior.
@@ -493,11 +493,11 @@ loss of the specified overflow behavior. This is the main warning in the
493493
// [-Wimplicit-overflow-behavior-conversion]
494494
}
495495

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:
497497

498498
.. code-block:: c++
499499

500-
typedef int __no_wrap safe_int;
500+
typedef int __trap safe_int;
501501

502502
void bar(int x); // Function expects standard int
503503

@@ -514,7 +514,7 @@ integer type.
514514
.. code-block:: c++
515515

516516
typedef int __wrap wrapping_int;
517-
typedef int __no_wrap safe_int;
517+
typedef int __trap safe_int;
518518

519519
void some_function() {
520520
wrapping_int w = 1;
@@ -589,7 +589,7 @@ types when passed to any varargs function.
589589
#include <cstdio>
590590

591591
typedef int __wrap wrap_int;
592-
typedef unsigned int __no_wrap nowrap_uint;
592+
typedef unsigned int __trap nowrap_uint;
593593

594594
void example() {
595595
wrap_int wi = 42;
@@ -609,19 +609,17 @@ The format string checker uses the underlying type to determine compatibility,
609609
so ``int __wrap`` is fully compatible with
610610
``%d``, ``%i``, ``%x``, etc., just like a regular ``int`` would be.
611611

612-
-Woverflow-behavior-attribute-ignored
613-
-------------------------------------
612+
Using With Non-Integer Types
613+
----------------------------
614614

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
616616
a non-integer type.
617617

618618
.. code-block:: c++
619619

620620
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'
623622

624623
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'
627625

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ Attribute Changes in Clang
251251
--------------------------
252252

253253
- Introduced a new type attribute ``__attribute__((overflow_behavior))`` which
254-
currently accepts either ``wrap`` or ``no_wrap`` as an argument, enabling
254+
currently accepts either ``wrap`` or ``trap`` as an argument, enabling
255255
type-level control over overflow behavior.
256256

257257
Improvements to Clang's diagnostics

clang/docs/SanitizerSpecialCaseList.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,11 @@ instrumentation for it.
156156
$ cat foo.c
157157
// Force 'critical_type' to always have overflow checks,
158158
// overriding the ignorelist.
159-
typedef int __attribute__((overflow_behavior(no_wrap))) critical_type;
159+
typedef int __attribute__((overflow_behavior(trap))) critical_type;
160160
161161
void foo(int x) {
162162
critical_type a = x;
163-
a++; // Overflow is checked here due to the 'no_wrap' attribute.
163+
a++; // Overflow is checked here due to the 'trap' attribute.
164164
165165
int b = x;
166166
b++; // Overflow is NOT checked here due to the ignorelist.

clang/docs/UndefinedBehaviorSanitizer.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ The ``overflow_behavior`` attribute not only affects UBSan instrumentation
394394
but also changes the fundamental overflow behavior of arithmetic operations
395395
on the annotated type. Operations on types marked with ``wrap`` will have
396396
well-defined wrapping semantics, while operations on types marked with
397-
``no_wrap`` will be checked for overflow (regardless of global flags like
397+
``trap`` will be checked for overflow (regardless of global flags like
398398
``-fwrapv``).
399399

400400
The attribute also affects implicit type promotion rules: when an overflow
@@ -406,10 +406,10 @@ the constraints of the smallest annotated type in the expression.
406406

407407
For more information, see :doc:`OverflowBehaviorTypes`.
408408

409-
Enforcing Overflow Instrumentation with ``__attribute__((overflow_behavior(no_wrap)))``
409+
Enforcing Overflow Instrumentation with ``__attribute__((overflow_behavior(trap)))``
410410
---------------------------------------------------------------------------------------
411411

412-
Conversely, you can use ``__attribute__((overflow_behavior(no_wrap)))`` to
412+
Conversely, you can use ``__attribute__((overflow_behavior(trap)))`` to
413413
enforce overflow checks for a specific type, even when ``-fwrapv`` is enabled
414414
globally. This is useful for ensuring that critical calculations are always
415415
checked for overflow, regardless of the global compiler settings.

clang/include/clang/AST/TypeBase.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,8 +1152,8 @@ class QualType {
11521152
/// Returns true if it is a OverflowBehaviorType of Wrap kind.
11531153
bool isWrapType() const;
11541154

1155-
/// Returns true if it is a OverflowBehaviorType of NoWrap kind.
1156-
bool isNoWrapType() const;
1155+
/// Returns true if it is a OverflowBehaviorType of Trap kind.
1156+
bool isTrapType() const;
11571157

11581158
// Don't promise in the API that anything besides 'const' can be
11591159
// easily added.
@@ -6697,7 +6697,7 @@ class BTFTagAttributedType : public Type, public llvm::FoldingSetNode {
66976697

66986698
class OverflowBehaviorType : public Type, public llvm::FoldingSetNode {
66996699
public:
6700-
enum OverflowBehaviorKind { Wrap, NoWrap };
6700+
enum OverflowBehaviorKind { Wrap, Trap };
67016701

67026702
private:
67036703
friend class ASTContext; // ASTContext creates these
@@ -6713,9 +6713,7 @@ class OverflowBehaviorType : public Type, public llvm::FoldingSetNode {
67136713
OverflowBehaviorKind getBehaviorKind() const { return BehaviorKind; }
67146714

67156715
bool isWrapKind() const { return BehaviorKind == OverflowBehaviorKind::Wrap; }
6716-
bool isNoWrapKind() const {
6717-
return BehaviorKind == OverflowBehaviorKind::NoWrap;
6718-
}
6716+
bool isTrapKind() const { return BehaviorKind == OverflowBehaviorKind::Trap; }
67196717

67206718
bool isSugared() const { return false; }
67216719
QualType desugar() const { return getUnderlyingType(); }

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4046,20 +4046,22 @@ def note_cannot_use_trivial_abi_reason : Note<
40464046
// OverflowBehavior attribute
40474047
def err_overflow_behavior_unknown_ident
40484048
: Error<"'%0' is not a valid argument to attribute %1, only 'wrap' and "
4049-
"'no_wrap' "
4050-
"are supported">;
4051-
def warn_overflow_behavior_non_integer_type
4052-
: Warning<"%0 %select{attribute|specifier}2 cannot be applied to "
4053-
"non-integer type '%1'; %select{attribute|specifier}2 ignored">,
4054-
InGroup<OverflowBehaviorAttributeIgnored>;
4049+
"'trap' are supported">;
4050+
def err_overflow_behavior_non_integer_type
4051+
: Error<"%0 %select{attribute|specifier}2 cannot be applied to "
4052+
"non-integer type '%1'">;
40554053
def warn_overflow_behavior_attribute_disabled
40564054
: Warning<"%0 attribute is ignored because it is not enabled; pass "
40574055
"-foverflow-behavior-types">,
40584056
InGroup<OverflowBehaviorAttributeIgnored>;
4059-
def warn_conflicting_overflow_behavior_attributes
4060-
: Warning<"conflicting %select{'overflow_behavior' attributes|overflow "
4061-
"behavior specifiers}0 on the same type; 'no_wrap' takes "
4062-
"precedence over 'wrap'">,
4057+
def err_conflicting_overflow_behaviors
4058+
: Error<"conflicting %select{'overflow_behavior' attributes|overflow "
4059+
"behavior specification; specifier specifies '%1' but attribute "
4060+
"specifies "
4061+
"'%2'}0 on the same type">;
4062+
def warn_redundant_overflow_behaviors_mixed
4063+
: Warning<"redundant overflow behavior specification; both specifier and "
4064+
"attribute specify '%0'">,
40634065
InGroup<OverflowBehaviorAttributeIgnored>;
40644066
def warn_impcast_overflow_behavior_assignment
40654067
: Warning<"implicit conversion from %0 to %1 during assignment discards "

clang/include/clang/Basic/LangOptions.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ class LangOptionsBase {
121121
// __attribute__((overflow_behavior("wrap")))
122122
OB_Wrap,
123123

124-
// __attribute__((overflow_behavior("no_wrap")))
125-
OB_NoWrap,
124+
// __attribute__((overflow_behavior("trap")))
125+
OB_Trap,
126126

127127
// Signed types defined as wrapping via -fwrapv can still be instrumented
128128
// by sanitizers (PR82432). This field is needed to disambiguate canonical

clang/include/clang/Basic/TokenKinds.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,8 @@ KEYWORD(__objc_no , KEYALL)
351351
KEYWORD(__ptrauth , KEYALL)
352352

353353
// Overflow behavior types
354-
KEYWORD(__wrap , KEYALL)
355-
KEYWORD(__no_wrap , KEYALL)
354+
KEYWORD(__ob_wrap , KEYALL)
355+
KEYWORD(__ob_trap , KEYALL)
356356

357357
// C2y
358358
UNARY_EXPR_OR_TYPE_TRAIT(_Countof, CountOf, KEYNOCXX)

0 commit comments

Comments
 (0)