[clang] [Clang] Separate implicit int conversion on negation sign to new diagnostic group (PR #139429)
Yutong Zhu via cfe-commits
cfe-commits at lists.llvm.org
Fri May 16 06:12:54 PDT 2025
https://github.com/YutongZhuu updated https://github.com/llvm/llvm-project/pull/139429
>From b5a1833d97a77692d25d3f60d347da62bd8db7c1 Mon Sep 17 00:00:00 2001
From: Yutong Zhu <y25zhu at uwaterloo.ca>
Date: Fri, 16 May 2025 09:12:40 -0400
Subject: [PATCH] Separate implicit int conversion on negation sign to new
diagnostic group
---
clang/docs/ReleaseNotes.rst | 3 +
clang/include/clang/Basic/DiagnosticGroups.td | 4 +-
.../clang/Basic/DiagnosticSemaKinds.td | 3 +
clang/lib/Sema/SemaChecking.cpp | 6 ++
.../Sema/implicit-int-conversion-on-int.c | 64 +++++++++++++++++++
5 files changed, 79 insertions(+), 1 deletion(-)
create mode 100644 clang/test/Sema/implicit-int-conversion-on-int.c
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 11f62bc881b03..b72484a0adfe2 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -352,6 +352,9 @@ Improvements to Clang's diagnostics
- Now correctly diagnose a tentative definition of an array with static
storage duration in pedantic mode in C. (#GH50661)
+- Split diagnosis of implicit integer comparison on negation to a new diagnostic group ``-Wimplicit-int-comparison-on-negation``,
+ so user can turn it off independently.
+
Improvements to Clang's time-trace
----------------------------------
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index d97bbfee2e4d5..4ea8143438474 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -110,9 +110,11 @@ def DeprecatedOFast : DiagGroup<"deprecated-ofast">;
def ObjCSignedCharBoolImplicitIntConversion :
DiagGroup<"objc-signed-char-bool-implicit-int-conversion">;
def Shorten64To32 : DiagGroup<"shorten-64-to-32">;
+def ImplicitIntConversionOnNegation : DiagGroup<"implicit-int-conversion-on-negation">;
def ImplicitIntConversion : DiagGroup<"implicit-int-conversion",
[Shorten64To32,
- ObjCSignedCharBoolImplicitIntConversion]>;
+ ObjCSignedCharBoolImplicitIntConversion,
+ ImplicitIntConversionOnNegation]>;
def ImplicitConstIntFloatConversion : DiagGroup<"implicit-const-int-float-conversion">;
def ImplicitIntFloatConversion : DiagGroup<"implicit-int-float-conversion",
[ImplicitConstIntFloatConversion]>;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 180ca39bc07e9..d315f056e54e7 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4217,6 +4217,9 @@ def warn_impcast_integer_sign_conditional : Warning<
def warn_impcast_integer_precision : Warning<
"implicit conversion loses integer precision: %0 to %1">,
InGroup<ImplicitIntConversion>, DefaultIgnore;
+def warn_impcast_integer_precision_on_negation : Warning<
+ "implicit conversion loses integer precision: %0 to %1 on negation">,
+ InGroup<ImplicitIntConversionOnNegation>, DefaultIgnore;
def warn_impcast_high_order_zero_bits : Warning<
"higher order bits are zeroes after implicit conversion">,
InGroup<ImplicitIntConversion>, DefaultIgnore;
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index bffd0dd461d3d..4c505f7ce5044 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -12091,6 +12091,12 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC,
if (SourceMgr.isInSystemMacro(CC))
return;
+ if (const auto *UO = dyn_cast<UnaryOperator>(E)) {
+ if (UO->getOpcode() == UO_Minus)
+ return DiagnoseImpCast(*this, E, T, CC,
+ diag::warn_impcast_integer_precision_on_negation);
+ }
+
if (TargetRange.Width == 32 && Context.getIntWidth(E->getType()) == 64)
return DiagnoseImpCast(*this, E, T, CC, diag::warn_impcast_integer_64_32,
/* pruneControlFlow */ true);
diff --git a/clang/test/Sema/implicit-int-conversion-on-int.c b/clang/test/Sema/implicit-int-conversion-on-int.c
new file mode 100644
index 0000000000000..40003f4f8ada9
--- /dev/null
+++ b/clang/test/Sema/implicit-int-conversion-on-int.c
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 %s -verify -Wimplicit-int-conversion
+// RUN: %clang_cc1 %s -verify -Wimplicit-int-conversion -Wno-implicit-int-conversion-on-negation -DNO_DIAG
+
+char test_char(char x) {
+ return -x;
+#ifndef NO_DIAG
+ // expected-warning at -2 {{implicit conversion loses integer precision}}
+#else
+ // expected-no-diagnostics
+#endif
+}
+
+unsigned char test_unsigned_char(unsigned char x) {
+ return -x;
+#ifndef NO_DIAG
+ // expected-warning at -2 {{implicit conversion loses integer precision}}
+#else
+ // expected-no-diagnostics
+#endif
+}
+
+short test_short(short x) {
+ return -x;
+#ifndef NO_DIAG
+ // expected-warning at -2 {{implicit conversion loses integer precision}}
+#else
+ // expected-no-diagnostics
+#endif
+}
+
+unsigned short test_unsigned_short(unsigned short x) {
+ return -x;
+#ifndef NO_DIAG
+ // expected-warning at -2 {{implicit conversion loses integer precision}}
+#else
+ // expected-no-diagnostics
+#endif
+}
+
+// --- int-width and wider (should NOT warn) ---
+
+int test_i(int x) {
+ return -x; // no warning
+}
+
+unsigned int test_ui(unsigned int x) {
+ return -x; // no warning
+}
+
+long test_l(long x) {
+ return -x; // no warning
+}
+
+unsigned long test_ul(unsigned long x) {
+ return -x; // no warning
+}
+
+long long test_ll(long long x) {
+ return -x; // no warning
+}
+
+unsigned long long test_ull(unsigned long long x) {
+ return -x; // no warning
+}
\ No newline at end of file
More information about the cfe-commits
mailing list