From: yu.dongliang <18588496441@163.com> Date: Fri, 4 Oct 2024 15:31:52 +0000 (+0800) Subject: fix: macro pre-process error when arg has multi-words, X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=8ff25b3c8e35645123c4a91834f4cb8f135b7b91;p=scf.git fix: macro pre-process error when arg has multi-words, fix: DAG error for auto type cast 'int n = 2; sizeof(int) * n * n', fix: optimize const teq error for assert(0), macro extends as below: do { if (!0) printf(...); } while (0) --- diff --git a/core/scf_3ac.c b/core/scf_3ac.c index 4fbaf37..ea64fec 100644 --- a/core/scf_3ac.c +++ b/core/scf_3ac.c @@ -565,7 +565,6 @@ static int _3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag, int nb_operands0 int j; if (c->dsts) { - for (j = 0; j < c->dsts->size; j++) { dst = c->dsts->data[j]; @@ -626,6 +625,7 @@ static int _3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag, int nb_operands0 } } + printf("\n"); return 0; } @@ -635,6 +635,7 @@ int scf_3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag) scf_3ac_operand_t* dst; int ret = 0; + int i; if (scf_type_is_assign(c->op->type)) { @@ -687,7 +688,7 @@ int scf_3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag) || scf_type_is_assign_dereference(c->op->type) || scf_type_is_assign_pointer(c->op->type)) { - scf_dag_node_t* assign; + scf_dag_node_t* assign; assert(c->srcs); @@ -696,10 +697,8 @@ int scf_3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag) return -ENOMEM; scf_list_add_tail(dag, &assign->list); - int i; for (i = 0; i < c->srcs->size; i++) { - src = c->srcs->data[i]; - assert(src && src->node); + src = c->srcs->data[i]; ret = scf_dag_get_node(dag, src->node, &src->dag_node); if (ret < 0) @@ -712,7 +711,7 @@ int scf_3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag) } else if (SCF_OP_3AC_CMP == c->op->type || SCF_OP_3AC_TEQ == c->op->type) { - scf_dag_node_t* dn_cmp = scf_dag_node_alloc(c->op->type, NULL, NULL); + scf_dag_node_t* dn_cmp = scf_dag_node_alloc(c->op->type, NULL, NULL); scf_list_add_tail(dag, &dn_cmp->list); @@ -740,7 +739,7 @@ int scf_3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag) assert(c->dsts && 1 == c->dsts->size); dst = c->dsts->data[0]; - scf_dag_node_t* dn_setcc = scf_dag_node_alloc(c->op->type, NULL, NULL); + scf_dag_node_t* dn_setcc = scf_dag_node_alloc(c->op->type, NULL, NULL); scf_list_add_tail(dag, &dn_setcc->list); ret = scf_dag_get_node(dag, dst->node, &dst->dag_node); @@ -757,12 +756,13 @@ int scf_3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag) || SCF_OP_DEC_POST == c->op->type || SCF_OP_3AC_INC == c->op->type || SCF_OP_3AC_DEC == c->op->type) { - src = c->srcs->data[0]; assert(src->node->parent); - scf_variable_t* v_parent = _scf_operand_get(src->node->parent); - scf_dag_node_t* dn_parent = scf_dag_node_alloc(c->op->type, v_parent, NULL); + + scf_variable_t* v_parent = _scf_operand_get(src->node->parent); + scf_dag_node_t* dn_parent = scf_dag_node_alloc(c->op->type, v_parent, NULL); + scf_list_add_tail(dag, &dn_parent->list); ret = scf_dag_get_node(dag, src->node, &src->dag_node); @@ -778,14 +778,34 @@ int scf_3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag) assert(dst->node); dst->dag_node = dn_parent; } + + } else if (SCF_OP_TYPE_CAST == c->op->type) { + + src = c->srcs->data[0]; + dst = c->dsts->data[0]; + + ret = scf_dag_get_node(dag, src->node, &src->dag_node); + if (ret < 0) + return ret; + + ret = scf_dag_get_node(dag, dst->node, &dst->dag_node); + if (ret < 0) + return ret; + + if (!scf_dag_node_find_child(dst->dag_node, src->dag_node)) { + + ret = scf_dag_node_add_child(dst->dag_node, src->dag_node); + if (ret < 0) + return ret; + } + } else if (SCF_OP_RETURN == c->op->type) { if (c->srcs) { - scf_dag_node_t* dn_return = scf_dag_node_alloc(c->op->type, NULL, NULL); + scf_dag_node_t* dn_return = scf_dag_node_alloc(c->op->type, NULL, NULL); scf_list_add_tail(dag, &dn_return->list); - int i; for (i = 0; i < c->srcs->size; i++) { src = c->srcs->data[i]; @@ -803,16 +823,16 @@ int scf_3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag) scf_logd("c->op: %d, name: %s\n", c->op->type, c->op->name); } else { - int nb_operands0 = -1; - int nb_operands1 = -1; + int n_operands0 = -1; + int n_operands1 = -1; if (c->dsts) { dst = c->dsts->data[0]; assert(dst->node->op); - nb_operands0 = dst->node->op->nb_operands; - nb_operands1 = nb_operands0; + n_operands0 = dst->node->op->nb_operands; + n_operands1 = n_operands0; switch (c->op->type) { case SCF_OP_ARRAY_INDEX: @@ -821,23 +841,23 @@ int scf_3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag) case SCF_OP_3AC_DEC_POST_ARRAY_INDEX: case SCF_OP_VA_START: case SCF_OP_VA_ARG: - nb_operands0 = 3; + n_operands0 = 3; break; case SCF_OP_3AC_ADDRESS_OF_POINTER: case SCF_OP_VA_END: - nb_operands0 = 2; + n_operands0 = 2; break; case SCF_OP_CALL: - nb_operands0 = c->srcs->size; + n_operands0 = c->srcs->size; break; default: break; }; } - return _3ac_code_to_dag(c, dag, nb_operands0, nb_operands1); + return _3ac_code_to_dag(c, dag, n_operands0, n_operands1); } return 0; diff --git a/core/scf_dag.c b/core/scf_dag.c index da9f2bc..53182ad 100644 --- a/core/scf_dag.c +++ b/core/scf_dag.c @@ -327,6 +327,14 @@ scf_dag_node_t* scf_dag_node_alloc(int type, scf_variable_t* var, const scf_node return dn; } +int scf_dag_node_find_child(scf_dag_node_t* parent, scf_dag_node_t* child) +{ + if (parent->childs + && scf_vector_find(parent->childs, child)) + return 1; + return 0; +} + int scf_dag_node_add_child(scf_dag_node_t* parent, scf_dag_node_t* child) { if (!parent || !child) diff --git a/core/scf_dag.h b/core/scf_dag.h index f12135d..90e6443 100644 --- a/core/scf_dag.h +++ b/core/scf_dag.h @@ -102,6 +102,7 @@ int scf_dn_status_copy_alias(scf_dn_status_t* dst, scf_dn_status_t scf_dag_node_t* scf_dag_node_alloc(int type, scf_variable_t* var, const scf_node_t* node); int scf_dag_node_add_child (scf_dag_node_t* parent, scf_dag_node_t* child); +int scf_dag_node_find_child(scf_dag_node_t* parent, scf_dag_node_t* child); int scf_dag_node_same (scf_dag_node_t* dag_node, const scf_node_t* node); void scf_dag_node_free (scf_dag_node_t* dag_node); diff --git a/core/scf_lex_word.c b/core/scf_lex_word.c index 242bc82..25f847c 100644 --- a/core/scf_lex_word.c +++ b/core/scf_lex_word.c @@ -47,11 +47,13 @@ scf_lex_word_t* scf_lex_word_clone(scf_lex_word_t* w) break; case SCF_LEX_WORD_CONST_STRING: + if (w->data.s) { + w1->data.s = scf_string_clone(w->data.s); - w1->data.s = scf_string_clone(w->data.s); - if (!w1->data.s) { - free(w1); - return NULL; + if (!w1->data.s) { + free(w1); + return NULL; + } } break; @@ -86,8 +88,10 @@ scf_lex_word_t* scf_lex_word_clone(scf_lex_word_t* w) void scf_lex_word_free(scf_lex_word_t* w) { if (w) { - if (SCF_LEX_WORD_CONST_STRING == w->type) - scf_string_free(w->data.s); + if (SCF_LEX_WORD_CONST_STRING == w->type) { + if (w->data.s) + scf_string_free(w->data.s); + } if (w->text) scf_string_free(w->text); diff --git a/core/scf_operator.c b/core/scf_operator.c index f94eb87..7440af4 100644 --- a/core/scf_operator.c +++ b/core/scf_operator.c @@ -108,4 +108,3 @@ scf_operator_t* scf_find_base_operator_by_type(const int type) return NULL; } - diff --git a/core/scf_operator_dag.c b/core/scf_operator_dag.c index 786a15b..615d57d 100644 --- a/core/scf_operator_dag.c +++ b/core/scf_operator_dag.c @@ -455,9 +455,8 @@ scf_dag_operator_t* scf_dag_operator_find(int type) int scf_dag_expr_calculate(scf_list_t* h, scf_dag_node_t* node) { - if (!node) { + if (!node) return 0; - } if (!node->childs || 0 == node->childs->size) { diff --git a/core/scf_optimizer_basic_block.c b/core/scf_optimizer_basic_block.c index d2d99c3..0e389d8 100644 --- a/core/scf_optimizer_basic_block.c +++ b/core/scf_optimizer_basic_block.c @@ -272,4 +272,3 @@ scf_optimizer_t scf_optimizer_basic_block = .flags = SCF_OPTIMIZER_LOCAL, }; - diff --git a/core/scf_optimizer_const_teq.c b/core/scf_optimizer_const_teq.c index 45eaa7e..57086f0 100644 --- a/core/scf_optimizer_const_teq.c +++ b/core/scf_optimizer_const_teq.c @@ -1,6 +1,6 @@ #include"scf_optimizer.h" -static int _bb_dfs_del(scf_basic_block_t* bb, scf_function_t* f) +static void __bb_dfs_del(scf_basic_block_t* bb, scf_function_t* f) { scf_3ac_operand_t* dst; scf_basic_block_t* bb2; @@ -32,16 +32,24 @@ static int _bb_dfs_del(scf_basic_block_t* bb, scf_function_t* f) for (i = 0; i < bb->nexts->size; ) { bb2 = bb->nexts->data[i]; - assert(0 == scf_vector_del(bb ->nexts, bb2)); - assert(0 == scf_vector_del(bb2->prevs, bb)); + assert(0 == scf_vector_del(bb->nexts, bb2)); - if (bb2->prevs->size > 0) + if (bb2->prevs->size > 1) { + assert(0 == scf_vector_del(bb2->prevs, bb)); continue; + } assert(&bb2->list != scf_list_head(&f->basic_block_list_head)); - if (_bb_dfs_del(bb2, f) < 0) - return -1; + __bb_dfs_del(bb2, f); + + assert(0 == scf_vector_del(bb2->prevs, bb)); + + scf_logd("bb2: %#lx, bb2->index: %d, prevs->size: %d\n", 0xffff & (uintptr_t)bb2, bb2->index, bb2->prevs->size); + + scf_list_del(&bb2->list); + scf_basic_block_free(bb2); + bb2 = NULL; } if (scf_list_prev(&bb->list) != sentinel && @@ -67,11 +75,6 @@ static int _bb_dfs_del(scf_basic_block_t* bb, scf_function_t* f) } } } - - scf_list_del(&bb->list); - scf_basic_block_free(bb); - bb = NULL; - return 0; } static int __optimize_const_teq(scf_basic_block_t* bb, scf_function_t* f) @@ -213,9 +216,18 @@ static int __optimize_const_teq(scf_basic_block_t* bb, scf_function_t* f) assert(0 == scf_vector_del(bb->nexts, bb2)); - if (0 == bb2->prevs->size) { - if (_bb_dfs_del(bb2, f) < 0) - return -1; + if (0 == bb2->prevs->size && + &bb2->list != scf_list_head(&f->basic_block_list_head)) { + + assert(0 == scf_vector_add(bb2->prevs, bb)); + + __bb_dfs_del(bb2, f); + + assert(0 == scf_vector_del(bb2->prevs, bb)); + + scf_list_del(&bb2->list); + scf_basic_block_free(bb2); + bb2 = NULL; } } @@ -230,22 +242,43 @@ static int _optimize_const_teq(scf_ast_t* ast, scf_function_t* f, scf_vector_t* scf_list_t* bb_list_head = &f->basic_block_list_head; scf_list_t* l; scf_basic_block_t* bb; + scf_basic_block_t* bb2; if (scf_list_empty(bb_list_head)) return 0; - for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); - l = scf_list_next(l)) { - - bb = scf_list_data(l, scf_basic_block_t, list); + for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); l = scf_list_next(l)) { + bb = scf_list_data(l, scf_basic_block_t, list); if (!bb->cmp_flag) continue; int ret = __optimize_const_teq(bb, f); - if (ret < 0) { - scf_loge("\n"); + if (ret < 0) return ret; + } + + for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); ) { + bb = scf_list_data(l, scf_basic_block_t, list); + + l = scf_list_next(l); + + if (!bb->cmp_flag) + continue; + + if (0 == bb->prevs->size && scf_list_empty(&bb->code_list_head)) { + + int i; + for (i = 0; i < bb->nexts->size; ) { + bb2 = bb->nexts->data[i]; + + assert(0 == scf_vector_del(bb ->nexts, bb2)); + assert(0 == scf_vector_del(bb2->prevs, bb)); + } + + scf_list_del(&bb->list); + scf_basic_block_free(bb); + bb = NULL; } } @@ -260,4 +293,3 @@ scf_optimizer_t scf_optimizer_const_teq = .flags = SCF_OPTIMIZER_LOCAL, }; - diff --git a/core/scf_optimizer_pointer_alias.c b/core/scf_optimizer_pointer_alias.c index feb5441..93a9a74 100644 --- a/core/scf_optimizer_pointer_alias.c +++ b/core/scf_optimizer_pointer_alias.c @@ -103,7 +103,7 @@ static int _3ac_pointer_alias(scf_dag_node_t* alias, scf_3ac_code_t* c, scf_basi pointer = c->srcs->data[0]; - ret = scf_vector_del(c->srcs, pointer); + ret = scf_vector_del(c->srcs, pointer); if (ret < 0) { scf_loge("\n"); return ret; @@ -289,7 +289,7 @@ static int _alias_assign_dereference(scf_vector_t** paliases, scf_dag_node_t* dn if (1 == aliases->size) { status = aliases->data[0]; - if (SCF_DN_ALIAS_VAR == status->alias_type) { + if (SCF_DN_ALIAS_VAR == status->alias_type && !scf_variable_const_integer(status->alias->var)) { ret = _3ac_pointer_alias(status->alias, c, bb, bb_list_head); diff --git a/core/scf_pointer_alias.c b/core/scf_pointer_alias.c index 4015977..2ca47bf 100644 --- a/core/scf_pointer_alias.c +++ b/core/scf_pointer_alias.c @@ -967,7 +967,6 @@ static int _pointer_alias_var(scf_vector_t* aliases, scf_dag_node_t* dn_alias, s scf_list_t* l2; int ret; - int i; scf_logd("alias: v_%d_%d/%s\n", v->w->line, v->w->pos, v->w->text->data); @@ -1020,7 +1019,7 @@ static int _pointer_alias_var(scf_vector_t* aliases, scf_dag_node_t* dn_alias, s } return ret; - } else if (sizeof(void*) == dn_alias->var->size) { + } else if (sizeof(void*) == dn_alias->var->size || scf_variable_const_integer(dn_alias->var)) { ds = scf_dn_status_null(); if (!ds) diff --git a/examples/assert.c b/examples/assert.c new file mode 100644 index 0000000..ca1e410 --- /dev/null +++ b/examples/assert.c @@ -0,0 +1,15 @@ +int printf(const char* fmt, ...); + +#define assert(x) \ + do { \ + if (!(x)) {\ + printf("assert: '%s' failed. file: %s, line: %d\n", #x, __FILE__, __LINE__); \ + *(int*)0 = 0; \ + } \ + } while (0) + +int main() +{ + assert(0); + return 0; +} diff --git a/lex/scf_lex.c b/lex/scf_lex.c index 8aed106..e6f43a3 100644 --- a/lex/scf_lex.c +++ b/lex/scf_lex.c @@ -377,10 +377,15 @@ static int _lex_identity(scf_lex_t* lex, scf_lex_word_t** pword, scf_char_t* c0) if (w) w->data.u64 = lex->nb_lines; - } else if (!strcmp(s->data, "__func__")) { + } else if (!strcmp(s->data, "__FILE__")) { w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_STRING); + if (w) + w->data.s = scf_string_clone(lex->file); + + } else if (!strcmp(s->data, "__func__")) { + w = scf_lex_word_alloc(lex->file, lex->nb_lines, lex->pos, SCF_LEX_WORD_CONST_STRING); } else { int type = _find_key_word(s->data); @@ -574,7 +579,7 @@ static int _lex_macro(scf_lex_t* lex) break; if ('\n' == c2->c) - c->c = ' '; + c2->flag = 0; } } @@ -636,7 +641,9 @@ int __lex_pop_word(scf_lex_t* lex, scf_lex_word_t** pword) c = _lex_pop_char(lex); - while ('\n' == c->c || '\r' == c->c || '\t' == c->c || ' ' == c->c) { + while ('\n' == c->c + || '\r' == c->c || '\t' == c->c + || ' ' == c->c || '\\' == c->c) { if ('\n' == c->c) { lex->nb_lines++; @@ -1152,7 +1159,8 @@ static int __convert_str(scf_lex_word_t* h) return -ENOMEM; } - for (w = h->next; w; w = w->next) { + while ( h->next) { + w = h->next; if (SCF_LEX_WORD_CONST_STRING != w->type) s = w->text; @@ -1162,9 +1170,18 @@ static int __convert_str(scf_lex_word_t* h) int ret = scf_string_cat(h->data.s, s); if (ret < 0) return ret; + + ret = scf_string_cat(h->text, w->text); + if (ret < 0) + return ret; + + h->next = w->next; + + scf_lex_word_free(w); + w = NULL; } - scf_logw("h: %s, file: %s, line: %d\n", h->data.s->data, h->file->data, h->line); + scf_logw("h: '%s', file: %s, line: %d\n", h->data.s->data, h->file->data, h->line); return 0; } @@ -1221,7 +1238,7 @@ static int __use_macro(scf_lex_t* lex, scf_macro_t* m, scf_lex_word_t* use) continue; } - scf_logd("p: %s, line: %d, hash: %d\n", p->text->data, p->line, hash); + scf_logd("p: '%s', line: %d, hash: %d\n", p->text->data, p->line, hash); if (m->argv) { assert(argv); @@ -1235,24 +1252,29 @@ static int __use_macro(scf_lex_t* lex, scf_macro_t* m, scf_lex_word_t* use) } if (i < m->argv->size) { - w = argv->data[i]; + scf_lex_word_t** tmp = pp; - if (1 == hash) { - ret = __convert_str(w); - if (ret < 0) + for (w = argv->data[i]; w; w = w->next) { + + *pp = scf_lex_word_clone(w); + if (!*pp) { + ret = -ENOMEM; goto error; + } - scf_slist_clear(w->next, scf_lex_word_t, next, scf_lex_word_free); - w->next = NULL; - } + if (!strcmp((*pp)->text->data, "__LINE__")) + (*pp)->data.u64 = use->line; - *pp = w; - while (w) { - pp = &w->next; - w = w->next; + pp = &(*pp)->next; } - argv->data[i] = NULL; + if (1 == hash) { + ret = __convert_str(*tmp); + if (ret < 0) + goto error; + + pp = &(*tmp)->next; + } hash = 0; continue; @@ -1265,6 +1287,9 @@ static int __use_macro(scf_lex_t* lex, scf_macro_t* m, scf_lex_word_t* use) goto error; } + if (!strcmp((*pp)->text->data, "__LINE__")) + (*pp)->data.u64 = use->line; + pp = &(*pp)->next; hash = 0; diff --git a/lib/scf_capi.c b/lib/scf_capi.c index d95e89b..384b957 100644 --- a/lib/scf_capi.c +++ b/lib/scf_capi.c @@ -1,6 +1,10 @@ int printf(const char* fmt, ...); +int rand(); +void srand(uint32_t seed); +int atoi(const char* s); + void* malloc (uintptr_t size); void* calloc (uintptr_t n, uintptr_t size); void* realloc(void* p, uintptr_t size); @@ -15,6 +19,8 @@ void scf__auto_freep (void** pp, scf__release_pt* release); void scf__auto_freep_array(void** pp, int nb_pointers, scf__release_pt* release); void scf__auto_free_array (void** pp, int size, int nb_pointers, scf__release_pt* release); +uintptr_t time(uintptr_t* t); + uintptr_t strlen (const char *s); int strcmp (const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, uintptr_t n); diff --git a/parse/scf_dfa_expr.c b/parse/scf_dfa_expr.c index 53827a8..d4dc1a8 100644 --- a/parse/scf_dfa_expr.c +++ b/parse/scf_dfa_expr.c @@ -108,27 +108,22 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d) } var = SCF_VAR_ALLOC_BY_TYPE(id->identity, pt, 1, 1, f); - if (!var) { - scf_loge("var '%s' alloc failed\n", w->text->data); - return SCF_DFA_ERROR; - } + if (!var) + return -ENOMEM; + var->const_literal_flag = 1; } - scf_loge("var: %s, member_flag: %d, line: %d\n", var->w->text->data, var->member_flag, var->w->line); + scf_logd("var: %s, member_flag: %d, line: %d\n", var->w->text->data, var->member_flag, var->w->line); node = scf_node_alloc(w, var->type, var); - if (!node) { - scf_loge("var node '%s' alloc failed\n", w->text->data); - return SCF_DFA_ERROR; - } + if (!node) + return -ENOMEM; if (!d->expr) { d->expr = scf_expr_alloc(); - if (!d->expr) { - scf_loge("expr alloc failed\n"); - return SCF_DFA_ERROR; - } + if (!d->expr) + return -ENOMEM; } scf_logd("d->expr: %p, node: %p\n", d->expr, node); diff --git a/parse/scf_operator_handler_semantic.c b/parse/scf_operator_handler_semantic.c index 20b9a6e..265db38 100644 --- a/parse/scf_operator_handler_semantic.c +++ b/parse/scf_operator_handler_semantic.c @@ -1090,11 +1090,11 @@ static int _scf_op_semantic_return(scf_ast_t* ast, scf_node_t** nodes, int nb_no assert(nodes); scf_variable_t* fret = f->rets->data[i]; - scf_expr_t* e = nodes[i]; scf_variable_t* r = NULL; + scf_expr_t* e = nodes[i]; if (SCF_VAR_VOID == fret->type && 0 == fret->nb_pointers) { - scf_loge("void function needs no return value\n"); + scf_loge("void function needs no return value, file: %s, line: %d\n", e->parent->w->file->data, e->parent->w->line); return -1; } diff --git a/parse/scf_parse.c b/parse/scf_parse.c index 2930c0b..1c5344d 100644 --- a/parse/scf_parse.c +++ b/parse/scf_parse.c @@ -1896,7 +1896,7 @@ int scf_parse_compile_functions(scf_parse_t* parse, scf_vector_t* functions) } assert(scf_list_empty(&h)); -// scf_basic_block_print_list(&f->basic_block_list_head); + scf_basic_block_print_list(&f->basic_block_list_head); } int ret = scf_optimize(parse->ast, functions);