Skip to content

Commit b3b1714

Browse files
committed
Make UO_Minus and UO_Not having the same logic in TryGetExprRange
1 parent 995fd47 commit b3b1714

File tree

3 files changed

+11
-39
lines changed

3 files changed

+11
-39
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+
- The -Wimplicit-int-conversion warning no longer triggers for direct assignments between integer types narrower than int.
356+
However, -Wsign-compare can now incorrectly produce a warning when comparing a value to another with just one more bit of width.
357+
355358
Improvements to Clang's time-trace
356359
----------------------------------
357360

clang/lib/Sema/SemaChecking.cpp

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10626,25 +10626,7 @@ static std::optional<IntRange> TryGetExprRange(ASTContext &C, const Expr *E,
1062610626
case UO_AddrOf: // should be impossible
1062710627
return IntRange::forValueOfType(C, GetExprType(E));
1062810628

10629-
case UO_Minus: {
10630-
if (E->getType()->isUnsignedIntegerType()) {
10631-
return TryGetExprRange(C, UO->getSubExpr(), MaxWidth, InConstantContext,
10632-
Approximate);
10633-
}
10634-
10635-
std::optional<IntRange> SubRange = TryGetExprRange(
10636-
C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
10637-
10638-
if (!SubRange)
10639-
return std::nullopt;
10640-
10641-
// If the range was previously non-negative, we need an extra bit for the
10642-
// sign bit. If the range was not non-negative, we need an extra bit
10643-
// because the negation of the most-negative value is one bit wider than
10644-
// that value.
10645-
return IntRange(SubRange->Width + 1, false);
10646-
}
10647-
10629+
case UO_Minus:
1064810630
case UO_Not: {
1064910631
if (E->getType()->isUnsignedIntegerType()) {
1065010632
return TryGetExprRange(C, UO->getSubExpr(), MaxWidth, InConstantContext,
@@ -10659,6 +10641,10 @@ static std::optional<IntRange> TryGetExprRange(ASTContext &C, const Expr *E,
1065910641

1066010642
// The width increments by 1 if the sub-expression cannot be negative
1066110643
// since it now can be.
10644+
// This isn't technically correct for UO_Minus since we need an extra bit
10645+
// because the negation of the most-negative value is one bit wider than
10646+
// the original value. However, the correct version triggers many unwanted
10647+
// warnings.
1066210648
return IntRange(SubRange->Width + (int)SubRange->NonNegative, false);
1066310649
}
1066410650

clang/test/Sema/compare.c

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -454,30 +454,13 @@ int test20(int n) {
454454
}
455455
#endif
456456

457-
int test21(short n) {
458-
return -n == 32768; // no-warning
459-
}
460-
461-
#if TEST == 1
462-
int test22(short n) {
463-
return -n == 65536; // expected-warning {{result of comparison of 17-bit signed value == 65536 is always false}}
464-
}
465-
#endif
466-
467457
int test23(unsigned short n) {
468458
return ~n == 32768; // no-warning
469459
}
470460

471461
int test24(short n) {
472462
return ~n == 32767; // no-warning
473463
}
474-
475-
#if TEST == 1
476-
int test25(unsigned short n) {
477-
return ~n == 65536; // expected-warning {{result of comparison of 17-bit signed value == 65536 is always false}}
478-
}
479-
480-
int test26(short n) {
481-
return ~n == 32768; // expected-warning {{result of comparison of 16-bit signed value == 32768 is always false}}
482-
}
483-
#endif
464+
unsigned char test25(unsigned char n) {
465+
return -n; // no-warning
466+
}

0 commit comments

Comments
 (0)