[clang] fix crash & improve comparing on GenericSelectionExpr (PR #67458)
Ding Fei via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 26 10:10:17 PDT 2023
https://github.com/danix800 updated https://github.com/llvm/llvm-project/pull/67458
>From 35bdb04db16c79d68dbe6522d01a0a08b2840d69 Mon Sep 17 00:00:00 2001
From: dingfei <fding at feysh.com>
Date: Wed, 27 Sep 2023 01:01:06 +0800
Subject: [PATCH] [StructuralEquivalence] fix crash & improve comparing on
GenericSelectionExpr
1. fix crash on 'default' assoc which has no TypeSourceInfo (nullptr);
2. improve equivalency comparison on control expr & associated exprs.
---
clang/lib/AST/ASTStructuralEquivalence.cpp | 20 +++++++++++++++++
.../AST/StructuralEquivalenceTest.cpp | 22 +++++++++++++++++++
2 files changed, 42 insertions(+)
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 5b98d14dd3d9104..d9b2f045552d52c 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -247,6 +247,20 @@ class StmtComparer {
bool IsStmtEquivalent(const GenericSelectionExpr *E1,
const GenericSelectionExpr *E2) {
+ if (!IsStructurallyEquivalent(Context,
+ const_cast<Expr *>(E1->getControllingExpr()),
+ const_cast<Expr *>(E2->getControllingExpr())))
+ return false;
+
+ for (auto Pair : zip_longest(E1->getAssocExprs(), E2->getAssocExprs())) {
+ std::optional<Expr *> Child1 = std::get<0>(Pair);
+ std::optional<Expr *> Child2 = std::get<1>(Pair);
+ if (!Child1 || !Child2)
+ return false;
+ if (!IsStructurallyEquivalent(Context, *Child1, *Child2))
+ return false;
+ }
+
for (auto Pair : zip_longest(E1->getAssocTypeSourceInfos(),
E2->getAssocTypeSourceInfos())) {
std::optional<TypeSourceInfo *> Child1 = std::get<0>(Pair);
@@ -255,6 +269,12 @@ class StmtComparer {
if (!Child1 || !Child2)
return false;
+ if (!(*Child1) != !(*Child2))
+ return false;
+
+ if (!(*Child1))
+ continue;
+
if (!IsStructurallyEquivalent(Context, (*Child1)->getType(),
(*Child2)->getType()))
return false;
diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index 44d950cfe758f14..35c1385e73fb389 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -2091,6 +2091,28 @@ TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprOrderDiffers) {
EXPECT_FALSE(testStructuralMatch(t));
}
+TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprControlDiffers) {
+ auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
+ "_Generic(1u, unsigned int: 0, float: 1)", Lang_C99,
+ genericSelectionExpr());
+ EXPECT_FALSE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprAssocExprDiffers) {
+ auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, float: 1)",
+ "_Generic(0u, unsigned int: 1u, float: 1)", Lang_C99,
+ genericSelectionExpr());
+ EXPECT_FALSE(testStructuralMatch(t));
+}
+
+TEST_F(StructuralEquivalenceStmtTest,
+ GenericSelectionExprDefaultNoTypeSourceInfo) {
+ auto t = makeWrappedStmts("_Generic(0u, unsigned int: 0, default: 1)",
+ "_Generic(0u, unsigned int: 0, default: 1)",
+ Lang_C99, genericSelectionExpr());
+ EXPECT_TRUE(testStructuralMatch(t));
+}
+
TEST_F(StructuralEquivalenceStmtTest, GenericSelectionExprDependentResultSame) {
auto t = makeStmts(
R"(
More information about the cfe-commits
mailing list