fix: crash in const_teq optimizer when the code like this 'while (1);'
authoryu.dongliang <18588496441@163.com>
Fri, 24 Mar 2023 04:41:44 +0000 (12:41 +0800)
committeryu.dongliang <18588496441@163.com>
Fri, 24 Mar 2023 04:41:44 +0000 (12:41 +0800)
core/scf_operator_handler_3ac.c
core/scf_optimizer_loop.c
native/x64/scf_x64.c
parse/scf_operator_handler_const.c
parse/scf_operator_handler_semantic.c

index 0ceac0a6c3ea343b31d8fa3253f5177e56603d03..6d2ddf208760f65c481b514102b775181517253d 100644 (file)
@@ -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) {
index 7b4c94b7995f50a5d0e3f93d6f17f76ecb4f7262..1c2c712664f5c0e41282310808b9c4ebf3aeaa34 100644 (file)
@@ -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)
index bc211b9133d1f32ad3f139f603cb63385e415ed9..85fcbde3b5fde3df9c240b9bcdc2a73896c94f02 100644 (file)
@@ -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];
 
index 7b463195bdd421e7c672dd553c1a7e6bef05b0df..809ed8bd802185333db226746b10702da7791f49 100644 (file)
@@ -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;
 }
index 90a1f69e4790fadda1130856de6c010f21b20f39..7212141a7b55f757717f1027ec2866728e97900f 100644 (file)
@@ -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;