Skip to content

Commit dd3f28f

Browse files
committed
Force expressions with UO_Not to not be non-negative
1 parent 934c97d commit dd3f28f

File tree

3 files changed

+17
-0
lines changed

3 files changed

+17
-0
lines changed

clang/docs/ReleaseNotes.rst

+2
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ 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(~) as signed integers
139+
and throws warning if they are compared with unsigned integers (##18878).
138140

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

clang/lib/Sema/SemaChecking.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -10069,6 +10069,17 @@ 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_Not: {
10073+
std::optional<IntRange> SubRange = TryGetExprRange(
10074+
C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
10075+
if (!SubRange)
10076+
return std::nullopt;
10077+
10078+
// The width increments by 1 if the sub-expression cannot be negative
10079+
// since it now can be.
10080+
return IntRange(SubRange->Width + (int)!SubRange->NonNegative, false);
10081+
}
10082+
1007210083
default:
1007310084
return TryGetExprRange(C, UO->getSubExpr(), MaxWidth, InConstantContext,
1007410085
Approximate);

clang/test/Sema/compare.c

+4
Original file line numberDiff line numberDiff line change
@@ -419,3 +419,7 @@ 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+
}

0 commit comments

Comments
 (0)