From 711c92865deee8ac8d46e81708bd147fa148a38b Mon Sep 17 00:00:00 2001 From: Ocean Date: Wed, 11 Jun 2025 17:20:05 +0800 Subject: [PATCH] Fix Bad Reg Type in verifier phase Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICEBI4 Reason: unary tilde argument convert to integer in checker which avoids conversion to interger in etsgen. verifier catch it and breaks. Description: 1. preserve float/double type for unary tilde argument in checker; 2. convert float/double type to int/long for unary tilde argument in etsgen Signed-off-by: Ocean --- ets2panda/checker/ETSAnalyzerHelpers.cpp | 2 +- ets2panda/checker/ets/assignAnalyzer.cpp | 10 ++++ ets2panda/compiler/core/ETSGen.cpp | 10 +++- .../global_variable_init_in_function.ets | 32 +++++++++++ .../ets/unary_tilde/unary_tilde_double.ets | 56 +++++++++++++++++++ 5 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 ets2panda/test/runtime/ets/global_variable_init/global_variable_init_in_function.ets create mode 100644 ets2panda/test/runtime/ets/unary_tilde/unary_tilde_double.ets diff --git a/ets2panda/checker/ETSAnalyzerHelpers.cpp b/ets2panda/checker/ETSAnalyzerHelpers.cpp index 2a5443ae23..0ec9336a24 100644 --- a/ets2panda/checker/ETSAnalyzerHelpers.cpp +++ b/ets2panda/checker/ETSAnalyzerHelpers.cpp @@ -539,7 +539,7 @@ void SetTsTypeForUnaryExpression(ETSChecker *checker, ir::UnaryExpression *expr, break; } - expr->Argument()->SetTsType(expr->SetTsType(checker->SelectGlobalIntegerTypeForNumeric(operandType))); + expr->Argument()->SetTsType(expr->SetTsType(operandType)); break; } case lexer::TokenType::PUNCTUATOR_EXCLAMATION_MARK: { diff --git a/ets2panda/checker/ets/assignAnalyzer.cpp b/ets2panda/checker/ets/assignAnalyzer.cpp index 8b29b6e855..afa4af9eb1 100644 --- a/ets2panda/checker/ets/assignAnalyzer.cpp +++ b/ets2panda/checker/ets/assignAnalyzer.cpp @@ -581,6 +581,16 @@ void AssignAnalyzer::AnalyzeMethodDef(const ir::MethodDefinition *methodDef) CheckPendingExits(); + for (int initId = 0; initId < nextAdr_; initId++) { + const ir::AstNode *var = varDecls_[initId]; + if (!inits_.IsMember(initId)) { + continue; + } + if (var->Parent() != nullptr && var->Parent()->IsClassDefinition() && + var->Parent()->AsClassDefinition()->IsGlobal()) { + initsPrev.Incl(initId); + } + } inits_ = std::move(initsPrev); uninits_ = std::move(uninitsPrev); } diff --git a/ets2panda/compiler/core/ETSGen.cpp b/ets2panda/compiler/core/ETSGen.cpp index 149c12d4d5..4fdd8e02e1 100644 --- a/ets2panda/compiler/core/ETSGen.cpp +++ b/ets2panda/compiler/core/ETSGen.cpp @@ -2168,7 +2168,15 @@ void ETSGen::UnaryTilde(const ir::AstNode *node) return; } - switch (checker::ETSChecker::ETSType(GetAccumulatorType())) { + auto origEtsType = checker::ETSChecker::ETSType(GetAccumulatorType()); + if (origEtsType == checker::TypeFlag::FLOAT) { + CastToInt(node); + } else if (origEtsType == checker::TypeFlag::DOUBLE) { + CastToLong(node); + } + + auto etsType = checker::ETSChecker::ETSType(GetAccumulatorType()); + switch (etsType) { case checker::TypeFlag::LONG: { Sa().Emit(node); break; diff --git a/ets2panda/test/runtime/ets/global_variable_init/global_variable_init_in_function.ets b/ets2panda/test/runtime/ets/global_variable_init/global_variable_init_in_function.ets new file mode 100644 index 0000000000..e2db63031a --- /dev/null +++ b/ets2panda/test/runtime/ets/global_variable_init/global_variable_init_in_function.ets @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +let planner: Planner; + +class Planner { + extract(a: int) { return 1; } +} + +function TestA() { + planner = new Planner(); + change(1); +} + +function change(newValue: int): void { + let plan = planner.extract(1); + assertEQ(plan, 1); +} + +TestA() \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/unary_tilde/unary_tilde_double.ets b/ets2panda/test/runtime/ets/unary_tilde/unary_tilde_double.ets new file mode 100644 index 0000000000..90d004354f --- /dev/null +++ b/ets2panda/test/runtime/ets/unary_tilde/unary_tilde_double.ets @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +let NUMBER: number; +let NUMBER1: number[] = [1, 2]; + +function foo(): number { return 1; } + +class A { + public a: number; + static foo() { return 1; } +} + +export namespace M { + export let n: number; +} + +let objA = new A(); + +// number type var +let ResultIsNumber1 = ~NUMBER; +let ResultIsNumber2 = ~NUMBER1[0]; + +// number type literal +let ResultIsNumber3 = ~1; + +// number type expressions +let ResultIsNumber6 = ~objA.a; +let ResultIsNumber7 = ~M.n; +let ResultIsNumber8 = ~NUMBER1[0]; +let ResultIsNumber9 = ~foo(); +let ResultIsNumber10 = ~A.foo(); +let ResultIsNumber11 = ~(NUMBER + NUMBER); + +// multiple ~ operators +let ResultIsNumber12 = ~~NUMBER; +let ResultIsNumber13 = ~~~(NUMBER + NUMBER + NUMBER) + +// miss assignment operators +~NUMBER; +~foo(); +~objA.a; +~M.n; +~objA.a; \ No newline at end of file -- Gitee