
## 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>
34 lines
1.2 KiB
C++
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;
|
|
}
|