From 94aba01f5a203e376002e85fe22d2b2ad7fe3564 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Fri, 24 Mar 2023 12:41:44 +0800 Subject: [PATCH] fix: crash in const_teq optimizer when the code like this 'while (1);' --- core/scf_operator_handler_3ac.c | 10 ++++--- core/scf_optimizer_loop.c | 16 +++++------ native/x64/scf_x64.c | 3 ++ parse/scf_operator_handler_const.c | 12 ++++---- parse/scf_operator_handler_semantic.c | 40 ++++++++++++++------------- 5 files changed, 45 insertions(+), 36 deletions(-) diff --git a/core/scf_operator_handler_3ac.c b/core/scf_operator_handler_3ac.c index 0ceac0a..6d2ddf2 100644 --- a/core/scf_operator_handler_3ac.c +++ b/core/scf_operator_handler_3ac.c @@ -1123,7 +1123,7 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s static int _scf_op_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { - assert(2 == nb_nodes); + assert(2 == nb_nodes || 1 == nb_nodes); scf_handler_data_t* d = data; @@ -1150,9 +1150,11 @@ static int _scf_op_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* d->branch_ops = local_branch_ops; // while body - if (_scf_op_node(ast, nodes[1], d) < 0) { - scf_loge("\n"); - return -1; + if (2 == nb_nodes) { + if (_scf_op_node(ast, nodes[1], d) < 0) { + scf_loge("\n"); + return -1; + } } if (_scf_op_end_loop(start_prev, NULL, jmp_end, up_branch_ops, d) < 0) { diff --git a/core/scf_optimizer_loop.c b/core/scf_optimizer_loop.c index 7b4c94b..1c2c712 100644 --- a/core/scf_optimizer_loop.c +++ b/core/scf_optimizer_loop.c @@ -40,13 +40,13 @@ static int __bb_dfs_loop(scf_list_t* bb_list_head, scf_basic_block_t* bb, scf_ba if (ret < 0) return ret; + if (dom == bb) + return 0; + ret = scf_vector_add(loop, dom); if (ret < 0) return ret; - if (dom == bb) - return 0; - for (l = scf_list_tail(bb_list_head); l != scf_list_sentinel(bb_list_head); l = scf_list_prev(l)) { @@ -469,12 +469,12 @@ static int _bb_loop_add_pre_post(scf_function_t* f) jmp = scf_list_data(scf_list_next(&bbg->entry->list), scf_basic_block_t, list); - assert(jmp->jmp_flag); + if (jmp->jmp_flag) { - if (!jmp->jcc_flag) { - scf_loge("\n"); - return -EINVAL; - } + if (!jmp->jcc_flag) + return -EINVAL; + } else + jmp = bbg->entry; pre = scf_basic_block_alloc(); if (!pre) diff --git a/native/x64/scf_x64.c b/native/x64/scf_x64.c index bc211b9..85fcbde 100644 --- a/native/x64/scf_x64.c +++ b/native/x64/scf_x64.c @@ -732,6 +732,9 @@ static int _x64_bbg_fix_saves(scf_bb_group_t* bbg, scf_function_t* f) int i; // int j; + if (0 == bbg->posts->size) + return 0; + pre = bbg->pre; post = bbg->posts->data[0]; diff --git a/parse/scf_operator_handler_const.c b/parse/scf_operator_handler_const.c index 7b46319..809ed8b 100644 --- a/parse/scf_operator_handler_const.c +++ b/parse/scf_operator_handler_const.c @@ -357,19 +357,21 @@ static int _scf_op_const_if(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, vo static int _scf_op_const_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { - assert(2 == nb_nodes); + assert(2 == nb_nodes || 1 == nb_nodes); scf_handler_data_t* d = data; + scf_variable_t* r = NULL; + scf_expr_t* e = nodes[0]; - scf_expr_t* e = nodes[0]; assert(SCF_OP_EXPR == e->type); - scf_variable_t* r = NULL; if (_scf_expr_calculate_internal(ast, e, &r) < 0) return -1; - if (_scf_op_const_node(ast, nodes[1], d) < 0) - return -1; + if (2 == nb_nodes) { + if (_scf_op_const_node(ast, nodes[1], d) < 0) + return -1; + } return 0; } diff --git a/parse/scf_operator_handler_semantic.c b/parse/scf_operator_handler_semantic.c index 90a1f69..7212141 100644 --- a/parse/scf_operator_handler_semantic.c +++ b/parse/scf_operator_handler_semantic.c @@ -1329,7 +1329,7 @@ static int _scf_op_semantic_if(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, static int _scf_op_semantic_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { - assert(2 == nb_nodes); + assert(2 == nb_nodes || 1 == nb_nodes); scf_handler_data_t* d = data; @@ -1352,32 +1352,34 @@ static int _scf_op_semantic_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nod r = NULL; // while body - scf_node_t* node = nodes[1]; - scf_operator_t* op = node->op; + if (2 == nb_nodes) { + scf_node_t* node = nodes[1]; + scf_operator_t* op = node->op; - if (!op) { - op = scf_find_base_operator_by_type(node->type); if (!op) { + op = scf_find_base_operator_by_type(node->type); + if (!op) { + scf_loge("\n"); + return -1; + } + } + + scf_operator_handler_t* h = scf_find_semantic_operator_handler(op->type, -1, -1, -1); + if (!h) { scf_loge("\n"); return -1; } - } - - scf_operator_handler_t* h = scf_find_semantic_operator_handler(op->type, -1, -1, -1); - if (!h) { - scf_loge("\n"); - return -1; - } - scf_variable_t** pret = d->pret; + scf_variable_t** pret = d->pret; - d->pret = &node->result; - int ret = h->func(ast, node->nodes, node->nb_nodes, d); - d->pret = pret; + d->pret = &node->result; + int ret = h->func(ast, node->nodes, node->nb_nodes, d); + d->pret = pret; - if (ret < 0) { - scf_loge("\n"); - return -1; + if (ret < 0) { + scf_loge("\n"); + return -1; + } } return 0; -- 2.25.1