Skip to content

Commit cc2a8f4

Browse files
committed
refactor OBT diagnostic groups and naming
Use -Wconversion diagnostic group patterns instead of hand-rolled ones. Signed-off-by: Justin Stitt <[email protected]>
1 parent ab4f0cc commit cc2a8f4

File tree

5 files changed

+98
-79
lines changed

5 files changed

+98
-79
lines changed

clang/docs/OverflowBehaviorTypes.rst

Lines changed: 59 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,10 @@ Diagnostics
161161

162162
Clang provides diagnostics to help developers manage overflow behavior types.
163163

164-
-Wimplicitly-discarded-overflow-behavior
165-
----------------------------------------
164+
-Woverflow-behavior-conversion
165+
------------------------------
166166

167-
This warning is issued when an overflow behavior type is implicitly converted
167+
This warning group is issued when an overflow behavior type is implicitly converted
168168
to a standard integer type, which may lead to the loss of the specified
169169
overflow behavior.
170170

@@ -192,39 +192,20 @@ integer type.
192192
some_function(static_cast<int>(w)); // OK
193193
}
194194

195-
This warning acts as a group that includes
196-
``-Wimplicitly-discarded-overflow-behavior-pedantic`` and
197-
``-Wimplicitly-discarded-overflow-behavior-assignment``.
198-
199-
-Wimplicitly-discarded-overflow-behavior-pedantic
200-
-------------------------------------------------
201-
202-
A less severe version of the warning, ``-Wimplicitly-discarded-overflow-behavior-pedantic``,
203-
is issued for implicit conversions from an unsigned wrapping type to a standard
204-
unsigned integer type. This is considered less problematic because both types
205-
have well-defined wrapping behavior, but the conversion still discards the
206-
explicit ``overflow_behavior`` attribute.
207-
208-
.. code-block:: c++
209-
210-
typedef unsigned int __attribute__((overflow_behavior(wrap))) wrapping_uint;
211-
212-
void some_function(unsigned int);
195+
This warning group includes
196+
``-Wimplicit-overflow-behavior-conversion`` and
197+
``-Wimplicit-overflow-behavior-conversion-pedantic``.
213198

214-
void another_function(wrapping_uint w) {
215-
some_function(w); // warning: implicit conversion from 'wrapping_uint' to
216-
// 'unsigned int' discards overflow behavior
217-
// [-Wimplicitly-discarded-overflow-behavior-pedantic]
218-
}
199+
.. note::
200+
``-Woverflow-behavior-conversion`` is implied by ``-Wconversion``.
219201

220-
-Wimplicitly-discarded-overflow-behavior-assignment
221-
---------------------------------------------------
202+
-Wimplicit-overflow-behavior-conversion
203+
---------------------------------------
222204

223205
This warning is issued when an overflow behavior type is implicitly converted
224-
to a standard integer type as part of an assignment, which may lead to the
225-
loss of the specified overflow behavior. This is a more specific version of
226-
the ``-Wimplicitly-discarded-overflow-behavior`` warning, and it is off by
227-
default.
206+
to a standard integer type as part of most conversions, which may lead to the
207+
loss of the specified overflow behavior. This is the main warning in the
208+
``-Woverflow-behavior-conversion`` group.
228209

229210
.. code-block:: c++
230211

@@ -233,8 +214,23 @@ default.
233214
void some_function() {
234215
wrapping_int w = 1;
235216
int i = w; // warning: implicit conversion from 'wrapping_int' to 'int'
236-
// discards overflow behavior
237-
// [-Wimplicitly-discarded-overflow-behavior-assignment]
217+
// during assignment discards overflow behavior
218+
// [-Wimplicit-overflow-behavior-conversion]
219+
}
220+
221+
Here's another example showing function parameter conversion with a ``no_wrap`` type:
222+
223+
.. code-block:: c++
224+
225+
typedef int __attribute__((overflow_behavior(no_wrap))) safe_int;
226+
227+
void bar(int x); // Function expects standard int
228+
229+
void foo() {
230+
safe_int s = 42;
231+
bar(s); // warning: implicit conversion from 'safe_int' to 'int'
232+
// discards overflow behavior
233+
// [-Wimplicit-overflow-behavior-conversion]
238234
}
239235

240236
To fix this, you can explicitly cast the overflow behavior type to a standard
@@ -243,13 +239,42 @@ integer type.
243239
.. code-block:: c++
244240

245241
typedef int __attribute__((overflow_behavior(wrap))) wrapping_int;
242+
typedef int __attribute__((overflow_behavior(no_wrap))) safe_int;
246243

247244
void some_function() {
248245
wrapping_int w = 1;
249246
int i = static_cast<int>(w); // OK
250247
int j = (int)w; // C-style OK
251248
}
252249

250+
void bar(int x);
251+
252+
void foo() {
253+
safe_int s = 42;
254+
bar(static_cast<int>(s)); // OK
255+
}
256+
257+
258+
-Wimplicit-overflow-behavior-conversion-pedantic
259+
------------------------------------------------
260+
261+
A less severe version of the warning, ``-Wimplicit-overflow-behavior-conversion-pedantic``,
262+
is issued for implicit conversions from an unsigned wrapping type to a standard
263+
unsigned integer type. This is considered less problematic because both types
264+
have well-defined wrapping behavior, but the conversion still discards the
265+
explicit ``overflow_behavior`` attribute.
266+
267+
.. code-block:: c++
268+
269+
typedef unsigned int __attribute__((overflow_behavior(wrap))) wrapping_uint;
270+
271+
void some_function(unsigned int);
272+
273+
void another_function(wrapping_uint w) {
274+
some_function(w); // warning: implicit conversion from 'wrapping_uint' to
275+
// 'unsigned int' discards overflow behavior
276+
// [-Wimplicit-overflow-behavior-conversion-pedantic]
277+
}
253278

254279
-Woverflow-behavior-attribute-ignored
255280
-------------------------------------

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -117,18 +117,11 @@ def ObjCSignedCharBoolImplicitIntConversion :
117117
DiagGroup<"objc-signed-char-bool-implicit-int-conversion">;
118118
def Shorten64To32 : DiagGroup<"shorten-64-to-32">;
119119
def ImplicitIntConversionOnNegation : DiagGroup<"implicit-int-conversion-on-negation">;
120-
def ImplicitIntConversion : DiagGroup<"implicit-int-conversion",
121-
[Shorten64To32,
120+
def ImplicitIntConversion
121+
: DiagGroup<
122+
"implicit-int-conversion", [Shorten64To32,
122123
ObjCSignedCharBoolImplicitIntConversion,
123124
ImplicitIntConversionOnNegation]>;
124-
def ImplicitlyDiscardedOverflowBehaviorPedantic
125-
: DiagGroup<"implicitly-discarded-overflow-behavior-pedantic">;
126-
def ImplicitlyDiscardedOverflowBehaviorAssignment
127-
: DiagGroup<"implicitly-discarded-overflow-behavior-assignment">;
128-
def ImplicitlyDiscardedOverflowBehavior
129-
: DiagGroup<"implicitly-discarded-overflow-behavior",
130-
[ImplicitlyDiscardedOverflowBehaviorPedantic,
131-
ImplicitlyDiscardedOverflowBehaviorAssignment]>;
132125
def ImplicitConstIntFloatConversion : DiagGroup<"implicit-const-int-float-conversion">;
133126
def ImplicitIntFloatConversion : DiagGroup<"implicit-int-float-conversion",
134127
[ImplicitConstIntFloatConversion]>;
@@ -138,6 +131,14 @@ def ImplicitFloatConversion : DiagGroup<"implicit-float-conversion",
138131
[ImplicitIntFloatConversion,
139132
ObjCSignedCharBoolImplicitFloatConversion]>;
140133
def ImplicitFixedPointConversion : DiagGroup<"implicit-fixed-point-conversion">;
134+
def ImplicitOverflowBehaviorConversion
135+
: DiagGroup<"implicit-overflow-behavior-conversion">;
136+
def ImplicitOverflowBehaviorConversionPedantic
137+
: DiagGroup<"implicit-overflow-behavior-conversion-pedantic">;
138+
def OverflowBehaviorConversion
139+
: DiagGroup<"overflow-behavior-conversion",
140+
[ImplicitOverflowBehaviorConversion,
141+
ImplicitOverflowBehaviorConversionPedantic]>;
141142

142143
def FloatOverflowConversion : DiagGroup<"float-overflow-conversion">;
143144
def FloatZeroConversion : DiagGroup<"float-zero-conversion">;
@@ -1145,23 +1146,16 @@ def Parentheses : DiagGroup<"parentheses",
11451146
// - conversion warnings for literals are on by default
11461147
// - bool-to-pointer conversion warnings are on by default
11471148
// - __null-to-integer conversion warnings are on by default
1148-
def Conversion : DiagGroup<"conversion",
1149-
[BoolConversion,
1150-
CharacterConversion,
1151-
ConstantConversion,
1152-
EnumConversion,
1153-
BitFieldEnumConversion,
1154-
FloatConversion,
1155-
IntConversion,
1156-
ImplicitIntConversion,
1157-
ImplicitFloatConversion,
1158-
LiteralConversion,
1159-
NonLiteralNullConversion, // (1-1)->pointer (etc)
1160-
NullConversion, // NULL->non-pointer
1161-
ObjCLiteralConversion,
1162-
SignConversion,
1163-
StringConversion]>,
1164-
DiagCategory<"Value Conversion Issue">;
1149+
def Conversion
1150+
: DiagGroup<"conversion",
1151+
[BoolConversion, CharacterConversion, ConstantConversion,
1152+
EnumConversion, BitFieldEnumConversion, FloatConversion,
1153+
IntConversion, ImplicitIntConversion, ImplicitFloatConversion,
1154+
OverflowBehaviorConversion, LiteralConversion,
1155+
NonLiteralNullConversion, // (1-1)->pointer (etc)
1156+
NullConversion, // NULL->non-pointer
1157+
ObjCLiteralConversion, SignConversion, StringConversion]>,
1158+
DiagCategory<"Value Conversion Issue">;
11651159

11661160
def Unused : DiagGroup<"unused",
11671161
[UnusedArgument, UnusedFunction, UnusedLabel,

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4043,16 +4043,14 @@ def warn_overflow_behavior_attribute_disabled
40434043
: Warning<"%0 attribute is ignored because it is not enabled; pass "
40444044
"-foverflow-behavior-types">,
40454045
InGroup<OverflowBehaviorAttributeIgnored>;
4046-
def warn_implicitly_discarded_overflow_behavior
4047-
: Warning<"implicit conversion from %0 to %1 discards overflow behavior">,
4048-
InGroup<ImplicitlyDiscardedOverflowBehavior>;
4049-
def warn_implicitly_discarded_overflow_behavior_pedantic
4050-
: Warning<"implicit conversion from %0 to %1 discards overflow behavior">,
4051-
InGroup<ImplicitlyDiscardedOverflowBehaviorPedantic>;
4052-
def warn_implicitly_discarded_overflow_behavior_assignment
4046+
def warn_impcast_overflow_behavior_assignment
40534047
: Warning<"implicit conversion from %0 to %1 during assignment discards "
40544048
"overflow behavior">,
4055-
InGroup<ImplicitlyDiscardedOverflowBehaviorAssignment>,
4049+
InGroup<ImplicitOverflowBehaviorConversion>,
4050+
DefaultIgnore;
4051+
def warn_impcast_overflow_behavior_pedantic
4052+
: Warning<"implicit conversion from %0 to %1 discards overflow behavior">,
4053+
InGroup<ImplicitOverflowBehaviorConversionPedantic>,
40564054
DefaultIgnore;
40574055
// Availability attribute
40584056
def warn_availability_unknown_platform : Warning<
@@ -4335,6 +4333,10 @@ def warn_impcast_vector_scalar : Warning<
43354333
def warn_impcast_complex_scalar : Warning<
43364334
"implicit conversion discards imaginary component: %0 to %1">,
43374335
InGroup<Conversion>, DefaultIgnore;
4336+
def warn_impcast_overflow_behavior
4337+
: Warning<"implicit conversion from %0 to %1 discards overflow behavior">,
4338+
InGroup<ImplicitOverflowBehaviorConversion>,
4339+
DefaultIgnore;
43384340
def err_impcast_complex_scalar : Error<
43394341
"implicit conversion from %0 to %1 is not permitted in C++">;
43404342
def warn_impcast_float_precision : Warning<

clang/lib/Sema/SemaChecking.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12153,17 +12153,15 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC,
1215312153
if (Target->isIntegerType() && !Target->isOverflowBehaviorType()) {
1215412154
// Implicit casts from unsigned wrap types to unsigned types are less
1215512155
// problematic but still warrant some diagnostic.
12156-
if (DiscardedDuringAssignment)
12157-
return DiagnoseImpCast(
12158-
*this, E, T, CC,
12159-
diag::warn_implicitly_discarded_overflow_behavior_assignment);
1216012156
if (OBT->isUnsignedIntegerType() && OBT->isWrapKind() &&
1216112157
Target->isUnsignedIntegerType())
12162-
return DiagnoseImpCast(
12163-
*this, E, T, CC,
12164-
diag::warn_implicitly_discarded_overflow_behavior_pedantic);
12158+
return DiagnoseImpCast(*this, E, T, CC,
12159+
diag::warn_impcast_overflow_behavior_pedantic);
12160+
if (DiscardedDuringAssignment)
12161+
return DiagnoseImpCast(*this, E, T, CC,
12162+
diag::warn_impcast_overflow_behavior_assignment);
1216512163
return DiagnoseImpCast(*this, E, T, CC,
12166-
diag::warn_implicitly_discarded_overflow_behavior);
12164+
diag::warn_impcast_overflow_behavior);
1216712165
}
1216812166
}
1216912167

clang/test/Sema/attr-overflow-behavior.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 %s -Winteger-overflow -Wno-unused-value -foverflow-behavior-types -Wimplicitly-discarded-overflow-behavior -verify -fsyntax-only
1+
// RUN: %clang_cc1 %s -Winteger-overflow -Wno-unused-value -foverflow-behavior-types -Woverflow-behavior-conversion -verify -fsyntax-only
22

33
typedef int __attribute__((overflow_behavior)) bad_arg_count; // expected-error {{'overflow_behavior' attribute takes one argument}}
44
typedef int __attribute__((overflow_behavior(not_real))) bad_arg_spec; // expected-error {{'not_real' is not a valid argument to attribute 'overflow_behavior'}}
@@ -34,7 +34,7 @@ void imp_disc_test(unsigned __attribute__((overflow_behavior(wrap))) a) {
3434
imp_disc(a); // expected-warning {{implicit conversion from '__wrap unsigned int' to 'int' discards overflow behavior}}
3535
}
3636

37-
// -Wimplicitly-discarded-overflow-behavior-assignment
37+
// -Wconversion for assignments that discard overflow behavior
3838
void assignment_disc_test(unsigned __attribute__((overflow_behavior(wrap))) a) {
3939
int b = a; // expected-warning {{implicit conversion from '__wrap unsigned int' to 'int' during assignment discards overflow behavior}}
4040
int c = (int)a; // OK

0 commit comments

Comments
 (0)