Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,10 @@ 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``, grouped under
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo here: it spells -Wimplicit-int-conversion-on-negation in the actual implementation

``-Wimplicit-int-conversion``, so user can turn it off independently.

Improvements to Clang's time-trace
----------------------------------

Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -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]>;
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
46 changes: 46 additions & 0 deletions clang/test/Sema/implicit-int-conversion-on-int.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// 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}}
}
Comment on lines +18 to +20
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last test and I think we're good:

unsigned _BitInt(16) test_unsigned_bit_int(unsigned _BitInt(16) x) {
  return -x;
}

this should not diagnose because _BitInt does not undergo promotion.


// --- 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;
}
Loading