diff --git a/src/eval.c b/src/eval.c index 0b49ecaa8..784411416 100644 --- a/src/eval.c +++ b/src/eval.c @@ -239,7 +239,7 @@ bool eval_possible(tree_t t, unit_registry_t *ur) if (tree_has_value(decl)) return eval_possible(tree_value(decl), ur); else - return true; + return false; default: return eval_not_possible(t, "reference"); diff --git a/src/lower.c b/src/lower.c index f7a0187c8..cfe01e4ba 100644 --- a/src/lower.c +++ b/src/lower.c @@ -2698,11 +2698,37 @@ static vcode_reg_t lower_link_var(lower_unit_t *lu, tree_t decl) istr(tree_ident(decl))); } } - else if (mode == LOWER_THUNK && lu->parent == NULL - && !arena_frozen(tree_arena(container))) { + else if (mode == LOWER_THUNK && lu->parent == NULL) { // Handle a special case of simplifying locally static expressions // that reference constant declarations - return lower_rvalue(lu, tree_value(decl)); + assert(tree_kind(decl) == T_CONST_DECL); + + type_t type = tree_type(decl); + tree_t value = tree_value(decl); + vcode_reg_t value_reg = lower_rvalue(lu, value), ptr_reg; + + switch (vcode_reg_kind(value_reg)) { + case VCODE_TYPE_POINTER: + case VCODE_TYPE_UARRAY: + ptr_reg = value_reg; + break; + default: + { + vcode_type_t vtype = lower_type(type); + vcode_type_t vbounds = lower_bounds(type); + vcode_var_t var = emit_var(vtype, vbounds, tree_ident(decl), 0); + lower_put_vcode_obj(decl, var, lu); + emit_store(value_reg, var); + + ptr_reg = emit_index(var, VCODE_INVALID_REG); + } + break; + } + + if (type_is_array(type)) + return lower_coerce_arrays(lu, tree_type(value), type, ptr_reg); + else + return ptr_reg; } assert(!is_uninstantiated_package(container)); diff --git a/test/simp/issue742.vhd b/test/simp/issue742.vhd new file mode 100644 index 000000000..d8575f053 --- /dev/null +++ b/test/simp/issue742.vhd @@ -0,0 +1,24 @@ +PACKAGE tb_test_package IS + + CONSTANT C_VEC : bit_vector(2 DOWNTO 0) := "111"; + + PROCEDURE test ( + o: OUT bit + ); + +END PACKAGE tb_test_package; + +PACKAGE BODY tb_test_package IS + + PROCEDURE test ( + o: OUT bit + ) IS + BEGIN + IF C_VEC /= "000" THEN + o := '1'; + ELSE + o := '0'; + END IF; + END test; + +END PACKAGE BODY tb_test_package; diff --git a/test/test_lower.c b/test/test_lower.c index 4894451d0..81e3857e6 100644 --- a/test/test_lower.c +++ b/test/test_lower.c @@ -2702,8 +2702,9 @@ START_TEST(test_thunk) vcode_select_unit(t0); EXPECT_BB(0) = { - { VCODE_OP_PACKAGE_INIT, .name = "WORK.PACK" }, - { VCODE_OP_LINK_VAR, .name = "C" }, + { VCODE_OP_CONST, .value = 1 }, + { VCODE_OP_CONST_ARRAY, .length = 4 }, + { VCODE_OP_ADDRESS_OF }, { VCODE_OP_CONST, .value = 2 }, { VCODE_OP_ARRAY_REF }, { VCODE_OP_LOAD_INDIRECT }, @@ -2715,29 +2716,6 @@ START_TEST(test_thunk) vcode_unit_unref(t0); } - - { - vcode_unit_t t1 = lower_thunk(NULL, tree_value(tree_decl(arch, 1))); - fail_if(t1 == NULL); - vcode_select_unit(t1); - - EXPECT_BB(0) = { - { VCODE_OP_PACKAGE_INIT, .name = "WORK.PACK" }, - { VCODE_OP_LINK_VAR, .name = "D" }, - { VCODE_OP_CONST, .value = 0 }, - { VCODE_OP_CONST, .value = 1 }, - { VCODE_OP_ARRAY_REF }, - { VCODE_OP_RECORD_REF, .field = 0 }, - { VCODE_OP_LOAD_INDIRECT }, - { VCODE_OP_DEBUG_LOCUS }, - { VCODE_OP_TRAP_ADD }, - { VCODE_OP_RETURN }, - }; - - CHECK_BB(0); - - vcode_unit_unref(t1); - } } END_TEST diff --git a/test/test_simp.c b/test/test_simp.c index 90068706e..508c377ab 100644 --- a/test/test_simp.c +++ b/test/test_simp.c @@ -1380,7 +1380,11 @@ START_TEST(test_genpack1) tree_t b0 = tree_stmt(top, 0); fail_unless(tree_kind(b0) == T_BLOCK); - fail_unless(tree_stmts(b0) == 0); + fail_unless(tree_stmts(b0) == 1); + + tree_t p1 = tree_stmt(b0, 0); + fail_unless(tree_kind(p1) == T_PROCESS); + fail_unless(tree_stmts(p1) == 2); // Should have been eliminated fail_if_errors(); } @@ -1520,6 +1524,21 @@ START_TEST(test_ieee1) } END_TEST +START_TEST(test_issue742) +{ + input_from_file(TESTDIR "/simp/issue742.vhd"); + + tree_t b = parse_check_and_simplify(T_PACKAGE, T_PACK_BODY); + + tree_t test = tree_decl(b, 0); + fail_unless(tree_kind(test) == T_PROC_BODY); + fail_unless(tree_stmts(test) == 1); + fail_unless(tree_kind(tree_stmt(test, 0)) == T_VAR_ASSIGN); + + fail_if_errors(); +} +END_TEST + Suite *get_simp_tests(void) { Suite *s = suite_create("simplify"); @@ -1578,6 +1597,7 @@ Suite *get_simp_tests(void) tcase_add_test(tc_core, test_casegen); tcase_add_test(tc_core, test_condexpr); tcase_add_test(tc_core, test_ieee1); + tcase_add_test(tc_core, test_issue742); suite_add_tcase(s, tc_core); return s;