Skip to content

Commit 4276937

Browse files
authored
[Parser] Check canonical types during type comparison (#24)
The canonical type check is done in addition to user type check so that when the user types are identical, the returned result retains the user type.
1 parent 5dae556 commit 4276937

File tree

3 files changed

+21
-9
lines changed

3 files changed

+21
-9
lines changed

lldb/source/ValueObject/DILParser.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,8 @@ UsualArithmeticConversions(std::shared_ptr<ExecutionContextScope> ctx,
486486
}
487487

488488
if (!is_comp_assign) {
489-
assert(lhs->GetDereferencedResultType().CompareTypes(rhs->GetDereferencedResultType()) &&
489+
assert(lhs->GetDereferencedResultType().GetCanonicalType().CompareTypes(
490+
rhs->GetDereferencedResultType().GetCanonicalType()) &&
490491
"integral promotion error: operands result types must be the same");
491492
}
492493

@@ -3409,6 +3410,12 @@ ASTNodeUP DILParser::BuildTernaryOp(ASTNodeUP cond, ASTNodeUP lhs,
34093410
return std::make_unique<TernaryOpNode>(location, lhs_type, std::move(cond),
34103411
std::move(lhs), std::move(rhs));
34113412
}
3413+
// If operands have the same canonical type, use the canonical type.
3414+
if (lhs_type.GetCanonicalType().CompareTypes(rhs_type.GetCanonicalType())) {
3415+
return std::make_unique<TernaryOpNode>(
3416+
location, lhs_type.GetCanonicalType(), std::move(cond), std::move(lhs),
3417+
std::move(rhs));
3418+
}
34123419

34133420
// If both operands have arithmetic type, apply the usual arithmetic
34143421
// conversions to bring them to a common type.
@@ -3434,6 +3441,12 @@ ASTNodeUP DILParser::BuildTernaryOp(ASTNodeUP cond, ASTNodeUP lhs,
34343441
return std::make_unique<TernaryOpNode>(location, lhs_type, std::move(cond),
34353442
std::move(lhs), std::move(rhs));
34363443
}
3444+
// Check if operands have the same canonical pointer type.
3445+
if (lhs_type.GetCanonicalType().CompareTypes(rhs_type.GetCanonicalType())) {
3446+
return std::make_unique<TernaryOpNode>(
3447+
location, lhs_type.GetCanonicalType(), std::move(cond), std::move(lhs),
3448+
std::move(rhs));
3449+
}
34373450

34383451
// If one operand is a pointer and the other is a nullptr or literal zero,
34393452
// convert the nullptr operand to pointer type.

lldb/unittests/DIL/DILTests.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3379,25 +3379,23 @@ TEST_F(EvalTest, TestTypeComparison) {
33793379
// This test is for border-case situations in the CompareTypes function.
33803380

33813381
// Taking an address of ternary expression require operands of the same type.
3382+
EXPECT_THAT(Eval("&(true ? i : mi)"), IsOk());
33823383
EXPECT_THAT(Eval("&(true ? ip : icpc)"), IsOk());
3383-
EXPECT_THAT(Eval("&(true ? mipp : ipp)"),
3384-
XFail(IsOk(/*compare_types*/ false)));
3384+
EXPECT_THAT(Eval("&(true ? mipp : ipp)"), IsOk(/*compare_types*/ false));
33853385
EXPECT_THAT(Eval("&(true ? ipp : icpcpc)"), IsOk());
3386-
EXPECT_THAT(Eval("&(true ? ipp : mipp)"), XFail(IsOk()));
3386+
EXPECT_THAT(Eval("&(true ? ipp : mipp)"), IsOk());
33873387
EXPECT_THAT(Eval("&(true ? ipp : micpcpc)"), IsOk());
33883388
// TODO: Enable type comparison once the type mismatch is fixed.
33893389
// LLDB results in "int ***", while lldb-eval results in "MyInt ***".
3390-
EXPECT_THAT(Eval("&(true ? mipp : icpcpc)"),
3391-
XFail(IsOk(/*compare_types*/ false)));
3392-
EXPECT_THAT(Eval("&(true ? mipp : micpcpc)"),
3393-
XFail(IsOk(/*compare_types*/ false)));
3390+
EXPECT_THAT(Eval("&(true ? mipp : icpcpc)"), IsOk(/*compare_types*/ false));
3391+
EXPECT_THAT(Eval("&(true ? mipp : micpcpc)"), IsOk(/*compare_types*/ false));
33943392
EXPECT_THAT(Eval("&(true ? icpcpc : micpcpc)"), IsOk());
33953393

33963394
// Ensure that "signed char" and "char" are different types.
33973395
EXPECT_THAT(Eval("true ? c : sc"), IsEqual("2")); // int
33983396
EXPECT_THAT(Eval("true ? sc : (signed char)67"), IsEqual("'A'"));
33993397
EXPECT_THAT(Eval("true ? (char)66 : (signed char)65"), IsEqual("66"));
3400-
EXPECT_THAT(Eval("true ? cc : mc"), XFail(IsEqual("'B'")));
3398+
EXPECT_THAT(Eval("true ? cc : mc"), IsEqual("'B'"));
34013399
EXPECT_THAT(Eval("true ? cc : sc"), IsEqual("66"));
34023400
EXPECT_THAT(Eval("true ? sc : mc"), IsEqual("65"));
34033401
EXPECT_THAT(Eval("&(true ? c : c)"), IsOk());

lldb/unittests/DIL/Inputs/test_binary.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,7 @@ void TestTypeComparison() {
10981098

10991099
using MyInt = int;
11001100
using MyPtr = MyInt *;
1101+
MyInt mi = 2;
11011102
MyPtr *mipp = ipp;
11021103

11031104
using MyConstInt = const int;

0 commit comments

Comments
 (0)