From 6b060e3a9d2c42c2ea5da00f56c543fe2f76ab1d Mon Sep 17 00:00:00 2001 From: varvara Date: Tue, 17 Jun 2025 17:48:53 +0300 Subject: [PATCH] Fix bugs related to primitives Fix number range check Restrict enum == number Fix constant arrow function folding Issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/ICR1XC Signed-off-by: tsatsulya --- ets2panda/checker/ETSAnalyzer.cpp | 5 +++++ ets2panda/checker/ets/arithmetic.cpp | 20 ++++++------------- .../ets/constantExpressionLowering.cpp | 10 +++++++++- .../ets/anno_interface_invalid_error.ets | 2 +- ets2panda/test/runtime/ets/Enum8.ets | 8 ++++---- .../ets/enum-numeric-operator-context.ets | 2 +- .../local-enum-numeric-operator-context.ets | 2 +- 7 files changed, 27 insertions(+), 22 deletions(-) diff --git a/ets2panda/checker/ETSAnalyzer.cpp b/ets2panda/checker/ETSAnalyzer.cpp index 75fa6aaf0f..090de9d8a9 100644 --- a/ets2panda/checker/ETSAnalyzer.cpp +++ b/ets2panda/checker/ETSAnalyzer.cpp @@ -2893,6 +2893,11 @@ static bool CheckIfLiteralValueIsAppropriate(ETSChecker *checker, Type *type, ir } return relation->IsIdenticalTo(checker->GlobalDoubleBuiltinType(), type); } + + if (relation->IsIdenticalTo(type, checker->GetGlobalTypesHolder()->GlobalCharBuiltinType())) { + auto charVal = number.GetValueAndCastTo(); + return charVal >= std::numeric_limits::min() && charVal <= std::numeric_limits::max(); + } return true; } diff --git a/ets2panda/checker/ets/arithmetic.cpp b/ets2panda/checker/ets/arithmetic.cpp index 0415b8a2ed..5256668786 100644 --- a/ets2panda/checker/ets/arithmetic.cpp +++ b/ets2panda/checker/ets/arithmetic.cpp @@ -171,10 +171,15 @@ static Type *BinaryGetPromotedType(ETSChecker *checker, Type *left, Type *right, { Type *const unboxedL = TryConvertToPrimitiveType(checker, left); Type *const unboxedR = TryConvertToPrimitiveType(checker, right); + if (unboxedL == nullptr || unboxedR == nullptr) { return nullptr; } + if (left->IsETSEnumType() || left->IsETSEnumType()) { + return nullptr; + } + Type *typeL = left; Type *typeR = right; @@ -185,9 +190,6 @@ static Type *BinaryGetPromotedType(ETSChecker *checker, Type *left, Type *right, } if (!bothBoxed) { - if (unboxedL->IsETSEnumType() || unboxedR->IsETSEnumType()) { - return nullptr; - } if (!typeL->IsETSPrimitiveType()) { typeL = checker->MaybeUnboxType(typeL); } @@ -289,7 +291,7 @@ static bool TypeIsAppropriateForArithmetic(const checker::Type *type, ETSChecker static checker::Type *CheckBinaryOperatorForIntEnums(ETSChecker *checker, checker::Type *const leftType, checker::Type *const rightType) { - if (!leftType->IsETSEnumType() && !rightType->IsETSEnumType()) { + if (!leftType->IsETSEnumType() || !rightType->IsETSEnumType()) { return nullptr; } if (TypeIsAppropriateForArithmetic(leftType, checker) && TypeIsAppropriateForArithmetic(rightType, checker)) { @@ -637,11 +639,6 @@ bool ETSChecker::CheckValidEqualReferenceType(checker::Type *const leftType, che } } - if (FindOpArgsType(this, leftType, rightType, GetGlobalTypesHolder()->GlobalNumericBuiltinType()) && - (leftType->IsETSEnumType() || rightType->IsETSEnumType())) { - return true; - } - // 7.24.5 Enumeration Relational Operators return leftType->IsETSEnumType() == rightType->IsETSEnumType(); } @@ -734,10 +731,6 @@ static bool NonNumericTypesAreAppropriateForComparison(ETSChecker *checker, Type (leftType->IsETSStringType() && rightType->IsETSStringEnumType())) { return true; } - if ((leftType->IsETSPrimitiveType() && rightType->IsETSIntEnumType()) || - (leftType->IsETSIntEnumType() && rightType->IsETSPrimitiveType())) { - return true; - } return false; } @@ -761,7 +754,6 @@ std::tuple ETSChecker::CheckBinaryOperatorLessGreater(ir::Expres } auto const promotedType = BinaryGetPromotedType(this, leftType, rightType, !isEqualOp); - if (leftType->IsETSUnionType() || rightType->IsETSUnionType()) { return {GlobalETSBooleanBuiltinType(), CreateETSUnionType({MaybeBoxExpression(left), MaybeBoxExpression(right)})}; diff --git a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp index 0d304337ed..5872b9c841 100644 --- a/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp +++ b/ets2panda/compiler/lowering/ets/constantExpressionLowering.cpp @@ -1236,7 +1236,15 @@ static bool IsConstantExpression(ir::AstNode *expr) if (expr->IsIdentifier()) { auto var = ResolveIdentifier(expr->AsIdentifier()); - return var != nullptr && var->Declaration()->IsConstDecl(); + if (var == nullptr || !var->Declaration()->IsConstDecl()) { + return false; + } + // ermolaevavarvara: Identifier is not constant if the variable is ArrowFunction (f.e. const foo = (n: number) + // => {} is not constant expr) + if (var->Declaration()->Node()->IsClassProperty()) { + return !var->Declaration()->Node()->AsClassProperty()->Value()->IsArrowFunctionExpression(); + } + return true; } if (expr->IsMemberExpression()) { diff --git a/ets2panda/test/ast/parser/ets/anno_interface_invalid_error.ets b/ets2panda/test/ast/parser/ets/anno_interface_invalid_error.ets index f3fefe0e9d..1afd59109a 100644 --- a/ets2panda/test/ast/parser/ets/anno_interface_invalid_error.ets +++ b/ets2panda/test/ast/parser/ets/anno_interface_invalid_error.ets @@ -39,7 +39,7 @@ const enum E1 { } -@Anno({a: E.A + 10, c: "a" + "b", d: (1 === 1), f: [], g: [[[0]]], h: E.A, i: [], j: E1.B, k: []}) +@Anno({a: E.A.valueOf() + 10, c: "a" + "b", d: (1 === 1), f: [], g: [[[0]]], h: E.A, i: [], j: E1.B, k: []}) class C{ @Anno({a: 10, b: [1, 2, 3], c: "cde", d: true, f: [1], g:[[[0], [1]]], h: E.A, i: [[[E.A], [E.B]]], j: E1.B, k: [[[E1.A], [E1.B]]]}) public foo() {} diff --git a/ets2panda/test/runtime/ets/Enum8.ets b/ets2panda/test/runtime/ets/Enum8.ets index edebc4ce29..db60266b8d 100644 --- a/ets2panda/test/runtime/ets/Enum8.ets +++ b/ets2panda/test/runtime/ets/Enum8.ets @@ -89,10 +89,10 @@ function main() { arktest.assertTrue((PermissionEnum.Read | PermissionEnum.Execute) === 5); arktest.assertTrue((PermissionEnum.Read ^ PermissionEnum.Write) === 3); - arktest.assertEQ(NumberEnum.Ten + 10, 20); - arktest.assertEQ(NumberEnum.Twenty - 10, 10); - arktest.assertEQ(NumberEnum.Thirty * 2, 60); - arktest.assertEQ(NumberEnum.Twenty / 2, 10); + arktest.assertEQ(NumberEnum.Ten.valueOf() + 10, 20); + arktest.assertEQ(NumberEnum.Twenty.valueOf() - 10, 10); + arktest.assertEQ(NumberEnum.Thirty.valueOf() * 2, 60); + arktest.assertEQ(NumberEnum.Twenty.valueOf() / 2, 10); let volumeLevel = VolumeEnum.Medium; let message = volumeLevel === VolumeEnum.Low ? "Low Volume" : (volumeLevel === VolumeEnum.Medium ? "Medium Volume" : "High Volume"); arktest.assertEQ(message, "Medium Volume"); diff --git a/ets2panda/test/runtime/ets/enum-numeric-operator-context.ets b/ets2panda/test/runtime/ets/enum-numeric-operator-context.ets index 5cb887fd74..4a229e5452 100644 --- a/ets2panda/test/runtime/ets/enum-numeric-operator-context.ets +++ b/ets2panda/test/runtime/ets/enum-numeric-operator-context.ets @@ -14,5 +14,5 @@ */ enum Color { Red=3, Green=45, Blue=2 } -let i : int = 3 + Color.Green; +let i : int = 3 + Color.Green.valueOf(); arktest.assertEQ(i, 48) diff --git a/ets2panda/test/runtime/ets/local-enum-numeric-operator-context.ets b/ets2panda/test/runtime/ets/local-enum-numeric-operator-context.ets index 5b326ba326..e69ae41953 100644 --- a/ets2panda/test/runtime/ets/local-enum-numeric-operator-context.ets +++ b/ets2panda/test/runtime/ets/local-enum-numeric-operator-context.ets @@ -16,6 +16,6 @@ enum Color { Red=3, Green=45, Blue=2 } function main(): void { - let i : int = 3 + Color.Green; + let i : int = 3 + Color.Green.valueOf(); arktest.assertEQ(i, 48) } -- Gitee