Author: Yutong Zhu
Date: 2025-06-02T07:27:32-04:00
New Revision: 0ada5c7b1a52afb668bc42dd2d5573e5805433d1

URL: 
https://github.com/llvm/llvm-project/commit/0ada5c7b1a52afb668bc42dd2d5573e5805433d1
DIFF: 
https://github.com/llvm/llvm-project/commit/0ada5c7b1a52afb668bc42dd2d5573e5805433d1.diff

LOG: [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.

Added: 
    clang/test/Sema/implicit-int-conversion-on-int.c

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticGroups.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaChecking.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index dc97883de05d0..91b89a0946555 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -601,6 +601,10 @@ Improvements to Clang's diagnostics
   trigger a ``'Blue' is deprecated`` warning, which can be turned off with
   ``-Wno-deprecated-declarations-switch-case``.
 
+- Split diagnosis of implicit integer comparison on negation to a new
+  diagnostic group ``-Wimplicit-int-comparison-on-negation``, grouped under
+  ``-Wimplicit-int-conversion``, 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 60c650583801a..be75b9ee6e3f6 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -116,9 +116,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 efc842bb4c42e..6f1e8d9fc74e6 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4288,6 +4288,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 aba39c0eb3299..3193359923fdb 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -12304,6 +12304,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..f555893d9e17a
--- /dev/null
+++ b/clang/test/Sema/implicit-int-conversion-on-int.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 %s -verify=expected -Wimplicit-int-conversion
+// RUN: %clang_cc1 %s -verify=none -Wimplicit-int-conversion 
-Wno-implicit-int-conversion-on-negation
+
+// none-no-diagnostics
+
+char test_char(char x) {
+  return -x; // expected-warning {{implicit conversion loses integer 
precision: 'int' to 'char' on negation}}
+}
+
+unsigned char test_unsigned_char(unsigned char x) {
+  return -x; // expected-warning {{implicit conversion loses integer 
precision: 'int' to 'unsigned char' on negation}}
+}
+
+short test_short(short x) {
+  return -x; // expected-warning {{implicit conversion loses integer 
precision: 'int' to 'short' on negation}}
+}
+
+unsigned short test_unsigned_short(unsigned short x) {
+  return -x; // expected-warning {{implicit conversion loses integer 
precision: 'int' to 'unsigned short' on negation}}
+}
+
+// --- int-width and wider (should NOT warn) ---
+
+int test_i(int x) {
+  return -x;
+}
+
+unsigned int test_ui(unsigned int x) {
+  return -x;
+}
+
+long test_l(long x) {
+  return -x;
+}
+
+unsigned long test_ul(unsigned long x) {
+  return -x;
+}
+
+long long test_ll(long long x) {
+  return -x;
+}
+
+unsigned long long test_ull(unsigned long long x) {
+  return -x;
+}
+
+unsigned _BitInt(16) test_unsigned_bit_int(unsigned _BitInt(16) x) {
+  return -x;
+}


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

Reply via email to