From d71a523f878e3e0c0346e26e0916aa2210589e95 Mon Sep 17 00:00:00 2001 From: zengzengran Date: Tue, 12 Aug 2025 16:58:45 +0800 Subject: [PATCH] Fix NonNullExpr reference null/undefined crash Issue: https://gitee.com/openharmony/arkcompiler_ets_frontend/issues/ICSFKY Description: During the checker phase, if TsNonNullExpression points to null or undefined, a warning will be thrown, and the TsType of TsNonNullExpression will be set to the TsType of identifier. However, in UnboxLowering, if TsNonNullExpression points to null or undefined, it will return ETSNeverType. Using AsETSObjectType causes compilation crash. Adopt the same behavior as the checker at UnboxLoweing. Tested-by: ninja tests (passed) ets_testrunner (passed) Signed-off-by: zengzengran # --- .../compiler/lowering/ets/unboxLowering.cpp | 8 +++- .../test/runtime/ets/non_null_expr_null.ets | 45 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 ets2panda/test/runtime/ets/non_null_expr_null.ets diff --git a/ets2panda/compiler/lowering/ets/unboxLowering.cpp b/ets2panda/compiler/lowering/ets/unboxLowering.cpp index 2ad5b19d69..7dc46f5b7a 100644 --- a/ets2panda/compiler/lowering/ets/unboxLowering.cpp +++ b/ets2panda/compiler/lowering/ets/unboxLowering.cpp @@ -1354,7 +1354,13 @@ struct UnboxVisitor : public ir::visitor::EmptyAstVisitor { ReplaceInParent(nnexpr, nnexpr->Expr()); return; } - nnexpr->SetTsType(uctx_->checker->GetNonNullishType(nnexpr->Expr()->TsType())); + + // Keep the behavior consistent with Check(ir::TSNonNullExpression *expr) + // If the actual [smart] type is definitely 'null' or 'undefined', throw a warning and return originalType + auto *exprType = + nnexpr->Expr()->TsType()->DefinitelyETSNullish() ? nnexpr->Check(uctx_->checker) : nnexpr->Expr()->TsType(); + + nnexpr->SetTsType(uctx_->checker->GetNonNullishType(exprType)); nnexpr->SetOriginalType(nnexpr->TsType()); } diff --git a/ets2panda/test/runtime/ets/non_null_expr_null.ets b/ets2panda/test/runtime/ets/non_null_expr_null.ets new file mode 100644 index 0000000000..abb55e298b --- /dev/null +++ b/ets2panda/test/runtime/ets/non_null_expr_null.ets @@ -0,0 +1,45 @@ +/* + * 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 { + field: string = "" + testNonNullExpr(): string { + let test: A | null = null; + try { + let field = test!.field; + } catch (error) { + return "Error" + } + return "Succ" + } + testNonNullExpr2(): string { + let test: A | undefined = undefined; + try { + let field = test!.field; + } catch (error) { + return "Error" + } + return "Succ" + } +} + +function main() { + let a = new A(); + let result = a.testNonNullExpr(); + arktest.assertEQ(result, "Error"); + + let result2 = a.testNonNullExpr2(); + arktest.assertEQ(result2, "Error"); +} -- Gitee