From 1aea9f5eae27d6cb6c3d39b524870f44d3f33e3b Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Thu, 20 Oct 2022 22:14:22 +0100 Subject: [PATCH] Fix bug with nested case/loop statement. Issue #539 --- src/lower.c | 10 +++---- src/vcode.c | 4 +++ test/regress/case14.vhd | 57 +++++++++++++++++++++++++++++++++++++++ test/regress/testlist.txt | 1 + 4 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 test/regress/case14.vhd diff --git a/src/lower.c b/src/lower.c index 6e075467..af2b99a5 100644 --- a/src/lower.c +++ b/src/lower.c @@ -5851,11 +5851,6 @@ static void lower_case_scalar(tree_t stmt, loop_stack_t *loops) static void lower_case_array(tree_t stmt, loop_stack_t *loops) { - vcode_block_t def_bb = VCODE_INVALID_BLOCK; - vcode_block_t exit_bb = emit_block(); - vcode_block_t hit_bb = VCODE_INVALID_BLOCK; - vcode_block_t start_bb = vcode_active_block(); - vcode_type_t vint64 = vtype_int(INT64_MIN, INT64_MAX); vcode_type_t voffset = vtype_offset(); @@ -5864,6 +5859,11 @@ static void lower_case_array(tree_t stmt, loop_stack_t *loops) vcode_reg_t val_reg = lower_rvalue(tree_value(stmt)); vcode_reg_t data_ptr = lower_array_data(val_reg); + vcode_block_t def_bb = VCODE_INVALID_BLOCK; + vcode_block_t exit_bb = emit_block(); + vcode_block_t hit_bb = VCODE_INVALID_BLOCK; + vcode_block_t start_bb = vcode_active_block(); + int64_t length = INT64_MAX; if (type_is_unconstrained(type) || !folded_length(range_of(type, 0), &length)) { diff --git a/src/vcode.c b/src/vcode.c index ab74e485..b5e31696 100644 --- a/src/vcode.c +++ b/src/vcode.c @@ -3160,6 +3160,10 @@ vcode_reg_t emit_cmp(vcode_cmp_t cmp, vcode_reg_t lhs, vcode_reg_t rhs) return emit_const(vtype_bool(), 1); else if (cmp == VCODE_CMP_NEQ) return emit_const(vtype_bool(), 0); + else if (cmp == VCODE_CMP_LEQ || cmp == VCODE_CMP_GEQ) + return emit_const(vtype_bool(), 1); + else if (cmp == VCODE_CMP_LT || cmp == VCODE_CMP_GT) + return emit_const(vtype_bool(), 0); } int64_t lconst, rconst; diff --git a/test/regress/case14.vhd b/test/regress/case14.vhd new file mode 100644 index 00000000..d21cc483 --- /dev/null +++ b/test/regress/case14.vhd @@ -0,0 +1,57 @@ +package my_package is + +type slv_1_t is array (natural range <>) of bit_vector; +type slv_2_t is array (natural range <>,natural range <>) of bit_vector; +subtype my_mat_t is slv_2_t(0 to 4-1,0 to 4-1)(8-1 downto 0); + +function my_function_f(arg0 : my_mat_t; constant arg2 : natural range 0 to 4-1) return slv_2_t; + +end package my_package; + +package body my_package is + +function my_function_f(arg0 : my_mat_t; constant arg2 : natural range 0 to 4-1) return slv_2_t is +variable retval : arg0'subtype; +variable my_var_v : slv_1_t(0 to 4-1)(8-1+3 downto 0); +begin +L1: for indI in retval'range(1) loop + L2: for indJ in retval'range(2) loop + case indJ=arg2 is + when false => null; + when true => + L3: for indK in 8 to 10 loop + -- Crash here due to control flow in case expression + case my_var_v(indI)(indK downto indK) is + when B"0" => report "zero"; + when B"1" => report "one"; + when others => NULL; + end case; + end loop; + when others => NULL; + end case; + end loop; +end loop; +return retval; +end function my_function_f; + +end package body; + +------------------------------------------------------------------------------- + +entity case14 is +end entity; + +use work.my_package.all; + +architecture test of case14 is +begin + + p1: process is + variable v : my_mat_t; + begin + wait for 1 ns; + assert my_function_f(v, 0) = v; + wait; + end process; + +end architecture; diff --git a/test/regress/testlist.txt b/test/regress/testlist.txt index 2b8ea4a5..f9a1b283 100644 --- a/test/regress/testlist.txt +++ b/test/regress/testlist.txt @@ -684,3 +684,4 @@ genpack12 normal,2008 wave8 shell signal28 normal,relaxed issue549 normal +case14 normal,2008 -- 2.39.2