From bf57cb1158ae17febb51d4fbff469a15a6ffa6da Mon Sep 17 00:00:00 2001 From: kumachan-mis <29433058+kumachan-mis@users.noreply.github.com> Date: Sun, 10 Dec 2023 06:45:20 +0000 Subject: [PATCH] fix resolver bug --- src/immcgen/statement.c | 2 +- src/resolver/resolver.c | 2 +- src/resolver/resolver.h | 2 +- src/resolver/statement.c | 25 ++++++++++++++++--------- tests/resolver/test_statement_error.c | 6 +++--- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/immcgen/statement.c b/src/immcgen/statement.c index aab4428a..ce9df315 100644 --- a/src/immcgen/statement.c +++ b/src/immcgen/statement.c @@ -20,7 +20,7 @@ Vector* gen_case_stmt_immcode(Immcgen* immcgen) { immcgen->label_id++; int case_label_id = immcgen->label_id; - Pair* label_value_pair = new_pair(&t_int, &t_iliteral); + Pair* label_value_pair = new_pair(&t_integer, &t_iliteral); pair_set(label_value_pair, new_integer(case_label_id), iliteral_copy(case_value_srt->iliteral)); vector_push(immcgen->case_label_values, label_value_pair); diff --git a/src/resolver/resolver.c b/src/resolver/resolver.c index 86ddbc61..3a8d2f60 100644 --- a/src/resolver/resolver.c +++ b/src/resolver/resolver.c @@ -39,7 +39,7 @@ void delete_resolver(Resolver* resolver) { delete_symboltable(resolver->symbol_table); delete_tagtable(resolver->tag_table); if (resolver->switch_cases != NULL) { - delete_set(resolver->switch_cases); + delete_vector(resolver->switch_cases); } if (resolver->return_dtype != NULL) { delete_dtype(resolver->return_dtype); diff --git a/src/resolver/resolver.h b/src/resolver/resolver.h index 7ba52508..7d6867d7 100644 --- a/src/resolver/resolver.h +++ b/src/resolver/resolver.h @@ -14,7 +14,7 @@ typedef struct Resolver { SymbolTable* symbol_table; TagTable* tag_table; int inside_loop; - Set* switch_cases; + Vector* switch_cases; int switch_default_exists; DType* return_dtype; DType* specifier_dtype; diff --git a/src/resolver/statement.c b/src/resolver/statement.c index d53effa4..b6bb3734 100644 --- a/src/resolver/statement.c +++ b/src/resolver/statement.c @@ -91,27 +91,33 @@ ResolverReturn* resolve_case_stmt(Resolver* resolver) { return new_resolverret_errors(errs); } - vector_push(srt->children, child_srt); - if (child_srt->type != SRT_ILITERAL_EXPR || iliteral_isunsigned(child_srt->iliteral)) { errs = new_vector(&t_error); err = new_error("only signed integer constant is supported as case label"); vector_push(errs, err); + delete_srt(child_srt); delete_srt(srt); return new_resolverret_errors(errs); } - int* case_value_integer = new_integer(child_srt->iliteral->signed_value); - if (set_contains(resolver->switch_cases, case_value_integer)) { + child_srt = perform_integer_promotion(child_srt); + vector_push(srt->children, child_srt); + + IntegerLiteral* case_value_iliteral = child_srt->iliteral; + int num_cases = vector_size(resolver->switch_cases); + for (int i = 0; i < num_cases; i++) { + IntegerLiteral* iliteral = vector_at(resolver->switch_cases, i); + if (iliteral->signed_value != case_value_iliteral->signed_value) { + continue; + } errs = new_vector(&t_error); err = new_error("value of case label is already used in switch"); vector_push(errs, err); delete_srt(srt); - free(case_value_integer); return new_resolverret_errors(errs); } - set_add(resolver->switch_cases, case_value_integer); + vector_push(resolver->switch_cases, iliteral_copy(case_value_iliteral)); resolver->ast = vector_at(ast->children, 1); resolverret_assign(&child_srt, &errs, resolve_stmt(resolver)); @@ -377,6 +383,7 @@ ResolverReturn* resolve_switch_stmt(Resolver* resolver) { child_srt = convert_to_ptr_if_array(child_srt); child_srt = convert_to_ptr_if_function(child_srt); + child_srt = perform_integer_promotion(child_srt); vector_push(srt->children, child_srt); if (!dtype_isinteger(child_srt->dtype)) { @@ -387,15 +394,15 @@ ResolverReturn* resolve_switch_stmt(Resolver* resolver) { return new_resolverret_errors(errs); } - Set* original_switch_cases = resolver->switch_cases; + Vector* original_switch_cases = resolver->switch_cases; int original_switch_default_exists = resolver->switch_default_exists; - resolver->switch_cases = new_set(&t_hashable_integer); + resolver->switch_cases = new_vector(&t_iliteral); resolver->ast = vector_at(ast->children, 1); resolverret_assign(&child_srt, &errs, resolve_stmt(resolver)); resolver->ast = ast; - delete_set(resolver->switch_cases); + delete_vector(resolver->switch_cases); resolver->switch_cases = original_switch_cases; resolver->switch_default_exists = original_switch_default_exists; diff --git a/tests/resolver/test_statement_error.c b/tests/resolver/test_statement_error.c index fcc37f6c..38a48ed0 100644 --- a/tests/resolver/test_statement_error.c +++ b/tests/resolver/test_statement_error.c @@ -545,7 +545,7 @@ void test_resolve_switch_stmt_error_condition_child(void) { Vector* expected = new_vector(&t_error); vector_push(expected, new_error("identifier 'x' is used before declared")); - run_stmt_resolver_error_test(input, NULL, NULL, expected); + run_stmt_resolver_error_test(input, local_table, NULL, expected); delete_vector(expected); } @@ -592,9 +592,9 @@ void test_resolve_switch_stmt_error_body_child(void) { symboltable_define_memory(local_table, new_string("x"), new_integer_dtype(DTYPE_INT)); Vector* expected = new_vector(&t_error); - vector_push(expected, new_error("identifier 'x' is used before declared")); + vector_push(expected, new_error("identifier 'y' is used before declared")); - run_stmt_resolver_error_test(input, NULL, NULL, expected); + run_stmt_resolver_error_test(input, local_table, NULL, expected); delete_vector(expected); }