llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Akash Manna (akash-manna-sky) <details> <summary>Changes</summary> Fixes #<!-- -->203575 `-1 == -*c`, where `c` points to a vector of `unsigned`, hit the `unsigned range includes negative?` assertion in `AnalyzeComparison`. The range analysis for unary `-` and `~` (added in #<!-- -->126846) checks whether the result type is unsigned with `isUnsignedIntegerType()`, which never looks through vector types. So the negated unsigned vector was treated as a signed negation and came back with a possibly-negative range, even though the operand's own range was correctly unsigned. Same story for `~*c`. The check now uses `hasUnsignedIntegerRepresentation()`, which looks through vector and matrix element types the same way `IntRange::forValueOfType` and the caller in `AnalyzeComparison` already do. The binary-operator result gets the same predicate for its non-negative fixup, since it had the identical blind spot. With that, a negated unsigned vector takes the same path as a negated `unsigned` scalar, and the comparison warns about mixed signs again as it did before Clang 21. --- Full diff: https://github.com/llvm/llvm-project/pull/223295.diff 3 Files Affected: - (modified) clang/docs/ReleaseNotes.md (+1) - (modified) clang/lib/Sema/SemaChecking.cpp (+3-3) - (modified) clang/test/Sema/compare.c (+19) ``````````diff diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 3cca316a91d4d..e9d681eb89a00 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -521,6 +521,7 @@ features cannot lower the translation-unit ABI level; - Fixed an assertion when `#pragma omp declare simd` or `#pragma omp declare variant` is followed by another OpenMP declarative directive containing a qualified identifier. (#GH217204) - Fixed a crash when an `asm` label names the register for a global variable of incomplete type. (#GH219746) - Fixed an ICE hat occurred when using `__imag int/float` as lvalue in assignment. (#GH119498) +- Fixed an assertion failure in `-Wsign-compare` when a negated or complemented vector of unsigned integers was compared against a signed constant. (#GH203575) #### Bug Fixes to Compiler Builtins diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 7374ce7404cbd..3b5523bf34d9b 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -12207,7 +12207,7 @@ static std::optional<IntRange> TryGetExprRange(ASTContext &C, const Expr *E, return std::nullopt; IntRange C = Combine(*L, *R); - C.NonNegative |= T->isUnsignedIntegerOrEnumerationType(); + C.NonNegative |= T->hasUnsignedIntegerRepresentation(); C.Width = std::min(C.Width, MaxWidth); return C; } @@ -12224,7 +12224,7 @@ static std::optional<IntRange> TryGetExprRange(ASTContext &C, const Expr *E, return IntRange::forValueOfType(C, GetExprType(E)); case UO_Minus: { - if (E->getType()->isUnsignedIntegerType()) { + if (GetExprType(E)->hasUnsignedIntegerRepresentation()) { return TryGetExprRange(C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate); } @@ -12242,7 +12242,7 @@ static std::optional<IntRange> TryGetExprRange(ASTContext &C, const Expr *E, } case UO_Not: { - if (E->getType()->isUnsignedIntegerType()) { + if (GetExprType(E)->hasUnsignedIntegerRepresentation()) { return TryGetExprRange(C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate); } diff --git a/clang/test/Sema/compare.c b/clang/test/Sema/compare.c index fdae3bc19841e..028d7bcfb3536 100644 --- a/clang/test/Sema/compare.c +++ b/clang/test/Sema/compare.c @@ -481,3 +481,22 @@ int test26(short n) { return ~n == 32768; // expected-warning {{result of comparison of 16-bit signed value == 32768 is always false}} } #endif + +// GH203575 +typedef unsigned gh203575_uvec __attribute__((__vector_size__(sizeof 2))); + +int gh203575_1(gh203575_uvec *c) { + return -1 == -*c; // expected-warning {{comparison of integers of different signs: 'int' and 'gh203575_uvec' (vector of 1 'unsigned int' value)}} +} + +int gh203575_2(gh203575_uvec *c) { + return - 8 == -*c; // expected-warning {{comparison of integers of different signs: 'int' and 'gh203575_uvec' (vector of 1 'unsigned int' value)}} +} + +int gh203575_3(gh203575_uvec *c) { + return -1 == ~*c; // expected-warning {{comparison of integers of different signs: 'int' and 'gh203575_uvec' (vector of 1 'unsigned int' value)}} +} + +int gh203575_4(gh203575_uvec a, gh203575_uvec b) { + return a == -b; // no-warning +} `````````` </details> https://github.com/llvm/llvm-project/pull/223295 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
