llvm-project/clang/test/Sema/warn-unreachable_crash.cpp
M. Zeeshan Siddiqui 70471f08ee
[Sema] Fix -Wunreachable-code false negative when operands differ only by implicit casts (#149972)
## Motivation  
`-Wunreachable-code` missed—or in rare cases crashed on—tautological
comparisons such as

```cpp
x != 0 || x != 1.0   // always true
x == 0 && x == 1.0   // always false
```

when the *same* variable appears on both sides but one operand goes
through a floating‑rank promotion that is target‑dependent. On back‑ends
with **native half‑precision** (`_Float16` / `__fp16`) such as
AArch64 `+fullfp16`, no promotion occurs, so the cast stacks between the
two operands differ and the existing heuristic bails out.

## Technical description 
* **Extends `Expr::isSameComparisonOperand()`** – the helper now ignores
parentheses **and value‑preserving implicit casts**
(`CK_LValueToRValue`, floating‑rank `CK_FloatingCast`) before comparing
the underlying operands. This prevents floating‑rank promotions and
lvalue‑to‑rvalue conversions from blocking the unreachable‑code
diagnostic on targets with native FP16.
*No change needed in `CheckIncorrectLogicOperator`; it simply benefits
from the improved helper.*
* **Regression test** – `warn-unreachable_crash.cpp` updated to cover
both the promoted case (x86‑64) and the native‑half case
(AArch64 `+fullfp16`).
* **Docs** – release‑note bullet added under *Bug Fixes in This
Version*.

@ziqingluo-90 @yronglin Could you please review promptly? (feel free to
also merge it on my behalf) Thanks!

Fixes #149967

Co-authored-by: Zeeshan Siddiqui <mzs@ntdev.microsoft.com>
2025-07-31 09:21:59 +08:00

34 lines
1.2 KiB
C++

// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -verify -Wunreachable-code %s
// RUN: %clang_cc1 -triple aarch64-unknown-linux-gnu -target-feature +fullfp16 -verify -Wunreachable-code %s
// REQUIRES: aarch64-registered-target
// ======= __fp16 version =======
static void test_fp16(__fp16 &x) {
if (x != 0 || x != 1.0) { // expected-note {{}} no-crash
x = 0.9;
} else
x = 0.8; // expected-warning{{code will never be executed}}
}
static void test_fp16_b(__fp16 &x) {
if (x != 1 && x == 1.0) { // expected-note {{}} no-crash
x = 0.9; // expected-warning{{code will never be executed}}
} else
x = 0.8;
}
// ======= _Float16 version =======
static void test_f16(_Float16 &x) {
if (x != 0 || x != 1.0) { // expected-note {{}} no-crash
x = 0.9;
} else
x = 0.8; // expected-warning{{code will never be executed}}
}
static void test_f16_b(_Float16 &x) {
if (x != 1 && x == 1.0) { // expected-note {{}} no-crash
x = 0.9; // expected-warning{{code will never be executed}}
} else
x = 0.8;
}