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 <y25...@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@-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@-2 {{implicit conversion loses integer precision}}
+#else
+  // expected-no-diagnostics
+#endif
+}
+
+short test_short(short x) {
+  return -x; 
+#ifndef NO_DIAG
+  // expected-warning@-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@-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

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to