[clang] [clang][CFG] Fix assertion failure in checkIncorrectLogicOperator (PR #142897)
Ziqing Luo via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 5 00:06:38 PDT 2025
https://github.com/ziqingluo-90 updated https://github.com/llvm/llvm-project/pull/142897
>From 99931f58846f361e409445d06fdfca4f5e7d3bb3 Mon Sep 17 00:00:00 2001
From: Ziqing Luo <ziqing at udel.edu>
Date: Thu, 5 Jun 2025 12:28:12 +0800
Subject: [PATCH 1/2] [clang][CFG] Fix assertion failure in
checkIncorrectLogicOperator
`checkIncorrectLogicOperator` checks if an expression, for example
`x != 0 || x != 1.0`, is always true or false by comparing the two
literals `0` and `1.0`. But in case `x` is a 16-bit float, the two
literals have distinct types---16-bit float and double, respectively.
Directly comparing `APValue`s extracted from the two literals results
in an assertion failure because of their distinct types.
This commit fixes the issue by doing a conversion from the "smaller"
one to the "bigger" one. The two literals must be compatible because
both of them are comparing with `x`.
rdar://152456316
---
clang/lib/Analysis/CFG.cpp | 22 ++++++++++++++++++++++
clang/test/Sema/warn-unreachable_crash.cpp | 8 ++++++++
2 files changed, 30 insertions(+)
create mode 100644 clang/test/Sema/warn-unreachable_crash.cpp
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp
index 7f37a8b18d46e..c9610cc2888ad 100644
--- a/clang/lib/Analysis/CFG.cpp
+++ b/clang/lib/Analysis/CFG.cpp
@@ -1261,6 +1261,28 @@ class CFGBuilder {
L2Result.Val.getKind() == APValue::Float) {
llvm::APFloat L1 = L1Result.Val.getFloat();
llvm::APFloat L2 = L2Result.Val.getFloat();
+ // Note that L1 and L2 do not necessarily have the same type. For example
+ // `x != 0 || x != 1.0`, if `x` is a float16, the two literals `0` and
+ // `1.0` are float16 and double respectively. In this case, we should do
+ // a conversion before comparing L1 and L2. Their types must be
+ // compatible since they are comparing with the same DRE.
+ int8_t Order = Context->getFloatingTypeOrder(NumExpr1->getType(),
+ NumExpr2->getType());
+ bool convertLoseInfo = false;
+
+ if (Order > 0) {
+ // type rank L1 > L2:
+ if (L2.convert(L1.getSemantics(), llvm::APFloat::rmNearestTiesToEven,
+ &convertLoseInfo))
+ return {};
+ } else if (Order < 0)
+ // type rank L1 < L2:
+ if (L1.convert(L2.getSemantics(), llvm::APFloat::rmNearestTiesToEven,
+ &convertLoseInfo))
+ return {};
+ if (convertLoseInfo)
+ return {}; // If the conversion loses info, bail
+
llvm::APFloat MidValue = L1;
MidValue.add(L2, llvm::APFloat::rmNearestTiesToEven);
MidValue.divide(llvm::APFloat(MidValue.getSemantics(), "2.0"),
diff --git a/clang/test/Sema/warn-unreachable_crash.cpp b/clang/test/Sema/warn-unreachable_crash.cpp
new file mode 100644
index 0000000000000..7b23f30c6a214
--- /dev/null
+++ b/clang/test/Sema/warn-unreachable_crash.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -verify -Wunreachable-code %s
+
+static void test(__fp16& x) {
+ if (x != 0 || x != 1.0) { // expected-note{{}}
+ x = 0.9;
+ } else
+ x = 0.8; // expected-warning{{code will never be executed}}
+}
>From 1729bb5b4ac8d3711bf1b1cb4451690c4fe461fe Mon Sep 17 00:00:00 2001
From: Ziqing Luo <ziqing at udel.edu>
Date: Thu, 5 Jun 2025 15:06:13 +0800
Subject: [PATCH 2/2] add test
---
clang/test/Sema/warn-unreachable_crash.cpp | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/clang/test/Sema/warn-unreachable_crash.cpp b/clang/test/Sema/warn-unreachable_crash.cpp
index 7b23f30c6a214..5fd4cf23744d5 100644
--- a/clang/test/Sema/warn-unreachable_crash.cpp
+++ b/clang/test/Sema/warn-unreachable_crash.cpp
@@ -1,8 +1,16 @@
// RUN: %clang_cc1 -verify -Wunreachable-code %s
+// Previously this test will crash
static void test(__fp16& x) {
if (x != 0 || x != 1.0) { // expected-note{{}}
x = 0.9;
} else
x = 0.8; // expected-warning{{code will never be executed}}
}
+
+static void test2(__fp16& x) {
+ if (x != 1 && x == 1.0) { // expected-note{{}}
+ x = 0.9; // expected-warning{{code will never be executed}}
+ } else
+ x = 0.8;
+}
More information about the cfe-commits
mailing list