From 615d45d3bf4bf1711e5a6228fdd1c5177f425332 Mon Sep 17 00:00:00 2001 From: fcc Date: Fri, 30 May 2025 17:46:51 +0800 Subject: [PATCH] fix equal comparison of numeric types CTE for numeric type comparing with non-numeric type. Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICC0IC Signed-off-by: fcc --- ets2panda/checker/ets/arithmetic.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index b0b3e32efd..d1a9a2b91c 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -657,7 +657,8 @@ static Type *CheckOperatorEqualDynamic(ETSChecker *checker, BinaryArithmOperands return checker->GlobalETSNullishObjectType(); } -static Type *HandelReferenceBinaryEquality(ETSChecker *checker, BinaryArithmOperands const &ops) +static Type *HandelReferenceBinaryEquality(ETSChecker *checker, BinaryArithmOperands const &ops, + lexer::SourcePosition pos) { [[maybe_unused]] auto const [expr, typeL, typeR, reducedL, reducedR] = ops; if ((typeR->IsETSNullType() && typeL->IsETSPrimitiveType()) || @@ -681,6 +682,22 @@ static Type *HandelReferenceBinaryEquality(ETSChecker *checker, BinaryArithmOper return checker->CreateETSUnionType({typeL, typeR}); } + Type *const unboxedL = TryConvertToPrimitiveType(checker, typeL); + Type *const unboxedR = TryConvertToPrimitiveType(checker, typeR); + bool hasPrimitiveConvertible = + !typeL->IsETSUnionType() && !typeR->IsETSUnionType() && + ((unboxedL == nullptr && unboxedR != nullptr) || (unboxedL != nullptr && unboxedR == nullptr)); + if (hasPrimitiveConvertible) { + checker->Relation()->SetNode(expr->Left()); + bool incompatible = + !checker->Relation()->IsCastableTo(typeL, typeR) && !checker->Relation()->IsCastableTo(typeR, typeL) && + !checker->Relation()->IsSupertypeOf(typeL, typeR) && !checker->Relation()->IsSupertypeOf(typeR, typeL); + if (incompatible) { + checker->LogError(diagnostic::BINOP_INCOMPARABLE, {}, pos); + return nullptr; + } + } + if ((reducedL->IsETSReferenceType() || reducedR->IsETSReferenceType()) && !(typeL->IsETSNullType() || typeL->IsETSUndefinedType()) && !(typeR->IsETSNullType() || typeR->IsETSUndefinedType())) { @@ -693,7 +710,7 @@ static Type *HandelReferenceBinaryEquality(ETSChecker *checker, BinaryArithmOper return nullptr; } -static Type *CheckBinaryOperatorEqual(ETSChecker *checker, BinaryArithmOperands const &ops) +static Type *CheckBinaryOperatorEqual(ETSChecker *checker, BinaryArithmOperands const &ops, lexer::SourcePosition pos) { [[maybe_unused]] auto const [expr, typeL, typeR, reducedL, reducedR] = ops; @@ -717,7 +734,7 @@ static Type *CheckBinaryOperatorEqual(ETSChecker *checker, BinaryArithmOperands return checker->GlobalETSBooleanType(); } - return HandelReferenceBinaryEquality(checker, ops); + return HandelReferenceBinaryEquality(checker, ops, pos); } // Satisfying the Chinese checker @@ -927,7 +944,7 @@ static std::tuple CheckBinaryOperatorHelper(ETSChecker *checker, case lexer::TokenType::PUNCTUATOR_NOT_STRICT_EQUAL: case lexer::TokenType::PUNCTUATOR_EQUAL: case lexer::TokenType::PUNCTUATOR_NOT_EQUAL: { - if (Type *res = CheckBinaryOperatorEqual(checker, opsRepaired); res != nullptr) { + if (Type *res = CheckBinaryOperatorEqual(checker, opsRepaired, pos); res != nullptr) { return {checker->GlobalETSBooleanType(), res}; } [[fallthrough]]; -- Gitee