Skip to content

Commit d740402

Browse files
committed
Fix no warning for comparison of integers of different signs
1 parent 934c97d commit d740402

File tree

3 files changed

+29
-0
lines changed

3 files changed

+29
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ Improvements to Clang's diagnostics
135135
- Fixed a bug where Clang's Analysis did not correctly model the destructor behavior of ``union`` members (#GH119415).
136136
- A statement attribute applied to a ``case`` label no longer suppresses
137137
'bypassing variable initialization' diagnostics (#84072).
138+
- The ``-Wsign-compare`` warning now treats expressions with bitwise not(~) and minus(-) as signed integers
139+
except for the case where the operand is an unsigned integer
140+
and throws warning if they are compared with unsigned integers (##18878).
138141

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

clang/lib/Sema/SemaChecking.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10069,6 +10069,24 @@ static std::optional<IntRange> TryGetExprRange(ASTContext &C, const Expr *E,
1006910069
case UO_AddrOf: // should be impossible
1007010070
return IntRange::forValueOfType(C, GetExprType(E));
1007110071

10072+
case UO_Minus:
10073+
case UO_Not: {
10074+
if (E->getType()->isUnsignedIntegerType()) {
10075+
return TryGetExprRange(C, UO->getSubExpr(), MaxWidth, InConstantContext,
10076+
Approximate);
10077+
}
10078+
10079+
std::optional<IntRange> SubRange = TryGetExprRange(
10080+
C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
10081+
10082+
if (!SubRange)
10083+
return std::nullopt;
10084+
10085+
// The width increments by 1 if the sub-expression cannot be negative
10086+
// since it now can be.
10087+
return IntRange(SubRange->Width + (int)SubRange->NonNegative, false);
10088+
}
10089+
1007210090
default:
1007310091
return TryGetExprRange(C, UO->getSubExpr(), MaxWidth, InConstantContext,
1007410092
Approximate);

clang/test/Sema/compare.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,3 +419,11 @@ void pr36008(enum PR36008EnumTest lhs) {
419419
if (x == y) x = y; // no warning
420420
if (y == x) y = x; // no warning
421421
}
422+
423+
int test13(unsigned a, int b) {
424+
return a > ~(95 != b); // expected-warning {{comparison of integers of different signs}}
425+
}
426+
427+
int test14(unsigned a, int b) {
428+
return a > -(95 != b); // expected-warning {{comparison of integers of different signs}}
429+
}

0 commit comments

Comments
 (0)