From c972b15ac1975469cb8767f81d5eab89829a3563 Mon Sep 17 00:00:00 2001 From: zengzengran Date: Sat, 5 Jul 2025 15:12:42 +0800 Subject: [PATCH] Fixing type alias as argument causes crash Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICJPCH Description: When type alias is used as argument of callexpression, report CTE. Tested-by: ninja tests (passed) ets_testrunner (passed) Signed-off-by: zengzengran # --- ets2panda/checker/ETSchecker.h | 1 - ets2panda/checker/ets/function.cpp | 11 ++-- .../compiler/ets/param_wrong_identifier.ets | 61 +++++++++++++++++++ .../runtime/ets/import_declare_type_alias.ets | 8 +-- 4 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 ets2panda/test/ast/compiler/ets/param_wrong_identifier.ets diff --git a/ets2panda/checker/ETSchecker.h b/ets2panda/checker/ETSchecker.h index 62c5776c6b2..2a61082efbf 100644 --- a/ets2panda/checker/ETSchecker.h +++ b/ets2panda/checker/ETSchecker.h @@ -468,7 +468,6 @@ public: bool ValidateSignatureInvocationContext(Signature *substitutedSig, ir::Expression *argument, std::size_t index, TypeRelationFlag flags); bool CheckOptionalLambdaFunction(ir::Expression *argument, Signature *substitutedSig, std::size_t index); - bool ValidateArgumentAsIdentifier(const ir::Identifier *identifier); bool IsValidRestArgument(ir::Expression *argument, Signature *substitutedSig, TypeRelationFlag flags, std::size_t index); bool SetPreferredTypeForArrayArgument(ir::ArrayExpression *arrayExpr, Signature *substitutedSig); diff --git a/ets2panda/checker/ets/function.cpp b/ets2panda/checker/ets/function.cpp index d2423c24ca3..44ae6a83cf9 100644 --- a/ets2panda/checker/ets/function.cpp +++ b/ets2panda/checker/ets/function.cpp @@ -385,10 +385,11 @@ bool ETSChecker::CheckOptionalLambdaFunction(ir::Expression *argument, Signature return false; } -bool ETSChecker::ValidateArgumentAsIdentifier(const ir::Identifier *identifier) +static bool IsInvalidArgumentAsIdentifier(varbinder::Scope *scope, const ir::Identifier *identifier) { - auto result = Scope()->Find(identifier->Name()); - return result.variable != nullptr && (result.variable->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE)); + auto result = scope->Find(identifier->Name()); + return result.variable != nullptr && (result.variable->HasFlag(varbinder::VariableFlags::CLASS_OR_INTERFACE | + varbinder::VariableFlags::TYPE_ALIAS)); } static void ClearPreferredTypeForArray(checker::ETSChecker *checker, ir::Expression *argument, Type *paramType, @@ -476,7 +477,7 @@ bool ETSChecker::ValidateSignatureRequiredParams(Signature *substitutedSig, ClearPreferredTypeForArray(this, argument, paramType, flags, false); - if (argument->IsIdentifier() && ValidateArgumentAsIdentifier(argument->AsIdentifier())) { + if (argument->IsIdentifier() && IsInvalidArgumentAsIdentifier(Scope(), argument->AsIdentifier())) { LogError(diagnostic::ARG_IS_CLASS_ID, {}, argument->Start()); return false; } @@ -2688,7 +2689,7 @@ bool ETSChecker::ValidateOrderSignatureRequiredParams(Signature *substitutedSig, return false; } - if (argument->IsIdentifier() && ValidateArgumentAsIdentifier(argument->AsIdentifier())) { + if (argument->IsIdentifier() && IsInvalidArgumentAsIdentifier(Scope(), argument->AsIdentifier())) { LogError(diagnostic::ARG_IS_CLASS_ID, {}, argument->Start()); return false; } diff --git a/ets2panda/test/ast/compiler/ets/param_wrong_identifier.ets b/ets2panda/test/ast/compiler/ets/param_wrong_identifier.ets new file mode 100644 index 00000000000..22b996e74db --- /dev/null +++ b/ets2panda/test/ast/compiler/ets/param_wrong_identifier.ets @@ -0,0 +1,61 @@ +/* + * 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. + */ + +class A { + foo1(a: number) { } + foo2(a: Number) { } + foo3(a: Int) { } + foo4(a: String) { } + static foo5(a: Boolean) { } + static foo6(a: number) { } +} +function foo7(a: number) { } + +function main() { + let a = new A(); + a.foo1(Number); + a.foo2(Number); + a.foo3(Int); + a.foo4(String); + A.foo5(Boolean); + A.foo6(Number); + foo7(Number); + const v1 = Number.isSafeInteger(Number); + try { + const v1 = Number.isSafeInteger(Number); + } catch (e) { } +} + +/* @@? 28:3 Error TypeError: No matching call signature for foo1(Double) */ +/* @@? 28:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 29:3 Error TypeError: No matching call signature for foo2(Double) */ +/* @@? 29:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 30:3 Error TypeError: No matching call signature for foo3(Int) */ +/* @@? 30:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 30:10 Error TypeError: Class or interface 'Int' cannot be used as object */ +/* @@? 31:3 Error TypeError: No matching call signature for foo4(String) */ +/* @@? 31:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 31:10 Error TypeError: Class or interface 'String' cannot be used as object */ +/* @@? 32:3 Error TypeError: No matching call signature for foo5(Boolean) */ +/* @@? 32:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 32:10 Error TypeError: Class or interface 'Boolean' cannot be used as object */ +/* @@? 33:3 Error TypeError: No matching call signature for foo6(Double) */ +/* @@? 33:10 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 34:3 Error TypeError: No matching call signature for foo7(Double) */ +/* @@? 34:8 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 35:14 Error TypeError: No matching call signature for isSafeInteger(Double) */ +/* @@? 35:35 Error TypeError: Class name can't be the argument of function or method. */ +/* @@? 37:16 Error TypeError: No matching call signature for isSafeInteger(Double) */ +/* @@? 37:37 Error TypeError: Class name can't be the argument of function or method. */ \ No newline at end of file diff --git a/ets2panda/test/runtime/ets/import_declare_type_alias.ets b/ets2panda/test/runtime/ets/import_declare_type_alias.ets index 4f0e85ba1a2..f502f6b3b0c 100644 --- a/ets2panda/test/runtime/ets/import_declare_type_alias.ets +++ b/ets2panda/test/runtime/ets/import_declare_type_alias.ets @@ -20,9 +20,9 @@ function main() { let type_array_var : type_array = new Array() let type_union_array_var : type_union_array = new Array() let type_array_alias_var : type_array_alias = new Array() - arktest.assertEQ((typeof type_union_var), string); - arktest.assertEQ((typeof type_array_var), object); - arktest.assertEQ((typeof type_union_array_var), object); - arktest.assertEQ((typeof type_array_alias_var), object); + arktest.assertEQ((typeof type_union_var), "string"); + arktest.assertEQ((typeof type_array_var), "object"); + arktest.assertEQ((typeof type_union_array_var), "object"); + arktest.assertEQ((typeof type_array_alias_var), "object"); } -- Gitee