Skip to content

Commit 0d2dcde

Browse files
committed
Separate implicit int conversion on negation sign to new diagnostic group
1 parent 995fd47 commit 0d2dcde

File tree

5 files changed

+79
-1
lines changed

5 files changed

+79
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,9 @@ Improvements to Clang's diagnostics
352352
- Now correctly diagnose a tentative definition of an array with static
353353
storage duration in pedantic mode in C. (#GH50661)
354354

355+
- Split diagnosis of implicit integer comparison on negation to a new diagnostic group ``-Wimplicit-int-comparison-on-negation``,
356+
so user can turn it off independently.
357+
355358
Improvements to Clang's time-trace
356359
----------------------------------
357360

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,11 @@ def DeprecatedOFast : DiagGroup<"deprecated-ofast">;
110110
def ObjCSignedCharBoolImplicitIntConversion :
111111
DiagGroup<"objc-signed-char-bool-implicit-int-conversion">;
112112
def Shorten64To32 : DiagGroup<"shorten-64-to-32">;
113+
def ImplicitIntConversionOnNegation : DiagGroup<"implicit-int-conversion-on-negation">;
113114
def ImplicitIntConversion : DiagGroup<"implicit-int-conversion",
114115
[Shorten64To32,
115-
ObjCSignedCharBoolImplicitIntConversion]>;
116+
ObjCSignedCharBoolImplicitIntConversion,
117+
ImplicitIntConversionOnNegation]>;
116118
def ImplicitConstIntFloatConversion : DiagGroup<"implicit-const-int-float-conversion">;
117119
def ImplicitIntFloatConversion : DiagGroup<"implicit-int-float-conversion",
118120
[ImplicitConstIntFloatConversion]>;

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4217,6 +4217,9 @@ def warn_impcast_integer_sign_conditional : Warning<
42174217
def warn_impcast_integer_precision : Warning<
42184218
"implicit conversion loses integer precision: %0 to %1">,
42194219
InGroup<ImplicitIntConversion>, DefaultIgnore;
4220+
def warn_impcast_integer_precision_on_negation : Warning<
4221+
"implicit conversion loses integer precision: %0 to %1 on negation">,
4222+
InGroup<ImplicitIntConversionOnNegation>, DefaultIgnore;
42204223
def warn_impcast_high_order_zero_bits : Warning<
42214224
"higher order bits are zeroes after implicit conversion">,
42224225
InGroup<ImplicitIntConversion>, DefaultIgnore;

clang/lib/Sema/SemaChecking.cpp

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

12094+
if (const auto *UO = dyn_cast<UnaryOperator>(E)) {
12095+
if (UO->getOpcode() == UO_Minus)
12096+
return DiagnoseImpCast(
12097+
*this, E, T, CC, diag::warn_impcast_integer_precision_on_negation);
12098+
}
12099+
1209412100
if (TargetRange.Width == 32 && Context.getIntWidth(E->getType()) == 64)
1209512101
return DiagnoseImpCast(*this, E, T, CC, diag::warn_impcast_integer_64_32,
1209612102
/* pruneControlFlow */ true);
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// RUN: %clang_cc1 %s -verify -Wimplicit-int-conversion
2+
// RUN: %clang_cc1 %s -verify -Wimplicit-int-conversion -Wno-implicit-int-conversion-on-negation -DNO_DIAG
3+
4+
char test_char(char x) {
5+
return -x;
6+
#ifndef NO_DIAG
7+
// expected-warning@-2 {{implicit conversion loses integer precision}}
8+
#else
9+
// expected-no-diagnostics
10+
#endif
11+
}
12+
13+
unsigned char test_unsigned_char(unsigned char x) {
14+
return -x;
15+
#ifndef NO_DIAG
16+
// expected-warning@-2 {{implicit conversion loses integer precision}}
17+
#else
18+
// expected-no-diagnostics
19+
#endif
20+
}
21+
22+
short test_short(short x) {
23+
return -x;
24+
#ifndef NO_DIAG
25+
// expected-warning@-2 {{implicit conversion loses integer precision}}
26+
#else
27+
// expected-no-diagnostics
28+
#endif
29+
}
30+
31+
unsigned short test_unsigned_short(unsigned short x) {
32+
return -x;
33+
#ifndef NO_DIAG
34+
// expected-warning@-2 {{implicit conversion loses integer precision}}
35+
#else
36+
// expected-no-diagnostics
37+
#endif
38+
}
39+
40+
// --- int-width and wider (should NOT warn) ---
41+
42+
int test_i(int x) {
43+
return -x; // no warning
44+
}
45+
46+
unsigned int test_ui(unsigned int x) {
47+
return -x; // no warning
48+
}
49+
50+
long test_l(long x) {
51+
return -x; // no warning
52+
}
53+
54+
unsigned long test_ul(unsigned long x) {
55+
return -x; // no warning
56+
}
57+
58+
long long test_ll(long long x) {
59+
return -x; // no warning
60+
}
61+
62+
unsigned long long test_ull(unsigned long long x) {
63+
return -x; // no warning
64+
}

0 commit comments

Comments
 (0)