Skip to content

Commit 0ada5c7

Browse files
authored
[Clang] Separate implicit int conversion on negation sign to new diagnostic group (#139429)
This PR reverts a change made in #126846. #126846 introduced an ``-Wimplicit-int-conversion`` diagnosis for ```c++ int8_t x = something; x = -x; // warning here ``` This is technically correct since -x could have a width of 9, but this pattern is common in codebases. Reverting this change would also introduce the false positive I fixed in #126846: ```c++ bool b(signed char c) { return -c >= 128; // -c can be 128 } ``` This false positive is uncommon, so I think it makes sense to revert the change.
1 parent c5a56f7 commit 0ada5c7

File tree

5 files changed

+66
-1
lines changed

5 files changed

+66
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,10 @@ Improvements to Clang's diagnostics
601601
trigger a ``'Blue' is deprecated`` warning, which can be turned off with
602602
``-Wno-deprecated-declarations-switch-case``.
603603

604+
- Split diagnosis of implicit integer comparison on negation to a new
605+
diagnostic group ``-Wimplicit-int-comparison-on-negation``, grouped under
606+
``-Wimplicit-int-conversion``, so user can turn it off independently.
607+
604608
Improvements to Clang's time-trace
605609
----------------------------------
606610

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,11 @@ def DeprecatedOFast : DiagGroup<"deprecated-ofast">;
116116
def ObjCSignedCharBoolImplicitIntConversion :
117117
DiagGroup<"objc-signed-char-bool-implicit-int-conversion">;
118118
def Shorten64To32 : DiagGroup<"shorten-64-to-32">;
119+
def ImplicitIntConversionOnNegation : DiagGroup<"implicit-int-conversion-on-negation">;
119120
def ImplicitIntConversion : DiagGroup<"implicit-int-conversion",
120121
[Shorten64To32,
121-
ObjCSignedCharBoolImplicitIntConversion]>;
122+
ObjCSignedCharBoolImplicitIntConversion,
123+
ImplicitIntConversionOnNegation]>;
122124
def ImplicitConstIntFloatConversion : DiagGroup<"implicit-const-int-float-conversion">;
123125
def ImplicitIntFloatConversion : DiagGroup<"implicit-int-float-conversion",
124126
[ImplicitConstIntFloatConversion]>;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4288,6 +4288,9 @@ def warn_impcast_integer_sign_conditional : Warning<
42884288
def warn_impcast_integer_precision : Warning<
42894289
"implicit conversion loses integer precision: %0 to %1">,
42904290
InGroup<ImplicitIntConversion>, DefaultIgnore;
4291+
def warn_impcast_integer_precision_on_negation : Warning<
4292+
"implicit conversion loses integer precision: %0 to %1 on negation">,
4293+
InGroup<ImplicitIntConversionOnNegation>, DefaultIgnore;
42914294
def warn_impcast_high_order_zero_bits : Warning<
42924295
"higher order bits are zeroes after implicit conversion">,
42934296
InGroup<ImplicitIntConversion>, DefaultIgnore;

clang/lib/Sema/SemaChecking.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12304,6 +12304,12 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC,
1230412304
if (SourceMgr.isInSystemMacro(CC))
1230512305
return;
1230612306

12307+
if (const auto *UO = dyn_cast<UnaryOperator>(E)) {
12308+
if (UO->getOpcode() == UO_Minus)
12309+
return DiagnoseImpCast(
12310+
*this, E, T, CC, diag::warn_impcast_integer_precision_on_negation);
12311+
}
12312+
1230712313
if (TargetRange.Width == 32 && Context.getIntWidth(E->getType()) == 64)
1230812314
return DiagnoseImpCast(*this, E, T, CC, diag::warn_impcast_integer_64_32,
1230912315
/* pruneControlFlow */ true);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// RUN: %clang_cc1 %s -verify=expected -Wimplicit-int-conversion
2+
// RUN: %clang_cc1 %s -verify=none -Wimplicit-int-conversion -Wno-implicit-int-conversion-on-negation
3+
4+
// none-no-diagnostics
5+
6+
char test_char(char x) {
7+
return -x; // expected-warning {{implicit conversion loses integer precision: 'int' to 'char' on negation}}
8+
}
9+
10+
unsigned char test_unsigned_char(unsigned char x) {
11+
return -x; // expected-warning {{implicit conversion loses integer precision: 'int' to 'unsigned char' on negation}}
12+
}
13+
14+
short test_short(short x) {
15+
return -x; // expected-warning {{implicit conversion loses integer precision: 'int' to 'short' on negation}}
16+
}
17+
18+
unsigned short test_unsigned_short(unsigned short x) {
19+
return -x; // expected-warning {{implicit conversion loses integer precision: 'int' to 'unsigned short' on negation}}
20+
}
21+
22+
// --- int-width and wider (should NOT warn) ---
23+
24+
int test_i(int x) {
25+
return -x;
26+
}
27+
28+
unsigned int test_ui(unsigned int x) {
29+
return -x;
30+
}
31+
32+
long test_l(long x) {
33+
return -x;
34+
}
35+
36+
unsigned long test_ul(unsigned long x) {
37+
return -x;
38+
}
39+
40+
long long test_ll(long long x) {
41+
return -x;
42+
}
43+
44+
unsigned long long test_ull(unsigned long long x) {
45+
return -x;
46+
}
47+
48+
unsigned _BitInt(16) test_unsigned_bit_int(unsigned _BitInt(16) x) {
49+
return -x;
50+
}

0 commit comments

Comments
 (0)