diff --git a/NEWS.md b/NEWS.md index a10c82b60..ece51ac9d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,6 +8,8 @@ certain conditions (#609). - The `-gNAME=VALUE` option to set generic values from the command line now works correctly for subtypes of enumeration types (#618). +- Fixed crash when creating an array of record subtypes where the + subtype declaration has an element constraint (#615). ## Version 1.8.1 - 2023-01-23 - Initial signal values for certain types were not dumped correctly in diff --git a/src/lower.c b/src/lower.c index 28babca41..887d204b3 100644 --- a/src/lower.c +++ b/src/lower.c @@ -4734,7 +4734,7 @@ static vcode_reg_t lower_default_value(type_t type, vcode_reg_t hint_reg, if (type_is_scalar(elem_type)) emit_store_indirect(def_reg, ptr_reg); else if (type_is_record(elem_type)) - emit_copy(ptr_reg, def_reg, VCODE_INVALID_REG); + lower_copy_record(elem_type, ptr_reg, def_reg, NULL); else emit_store_indirect(def_reg, ptr_reg); @@ -4763,8 +4763,15 @@ static vcode_reg_t lower_default_value(type_t type, vcode_reg_t hint_reg, mem_reg = emit_index(tmp_var, VCODE_INVALID_REG); } - tree_t rcon = shift_constraints(&cons, &ncons, 1); - assert(ncons == 0); // Cannot have more constraints following record + tree_t rcon = NULL; + if (ncons > 0) { + rcon = shift_constraints(&cons, &ncons, 1); + assert(ncons == 0); // Cannot have more constraints following record + } + else if (type_kind(type) == T_SUBTYPE && type_constraints(type) > 0) { + rcon = type_constraint(type, 0); + assert(tree_subkind(rcon) == C_RECORD); + } for (int i = 0; i < nfields; i++) { tree_t f = type_field(type, i); diff --git a/test/regress/gold/issue615.txt b/test/regress/gold/issue615.txt new file mode 100644 index 000000000..b0e4c6e3b --- /dev/null +++ b/test/regress/gold/issue615.txt @@ -0,0 +1,32 @@ +(32768,0) +(32138,6393) +(30274,12540) +(27246,18205) +(23170,23170) +(18205,27246) +(12540,30274) +(6393,32138) +(0,32768) +(-6393,32138) +(-12540,30274) +(-18205,27246) +(-23170,23170) +(-27246,18205) +(-30274,12540) +(-32138,6393) +(-32768,0) +(-32138,-6393) +(-30274,-12540) +(-27246,-18205) +(-23170,-23170) +(-18205,-27246) +(-12540,-30274) +(-6393,-32138) +(0,-32768) +(6393,-32138) +(12540,-30274) +(18205,-27246) +(23170,-23170) +(27246,-18205) +(30274,-12540) +(32138,-6393) diff --git a/test/regress/issue615.vhd b/test/regress/issue615.vhd new file mode 100644 index 000000000..5d127625f --- /dev/null +++ b/test/regress/issue615.vhd @@ -0,0 +1,58 @@ +-- Test case from Brian Padalino +library ieee ; + use ieee.std_logic_1164.all ; + use ieee.numeric_std.all ; + use ieee.math_real.all ; + + use std.textio.all ; + +entity issue615 is +end entity ; + +architecture arch of issue615 is + + constant LUT_DEPTH : positive := 32 ; + + type cx_t is record + re : signed ; + im : signed ; + end record ; + + function to_string(x : cx_t) return string is + begin + return "(" & + to_string(to_integer(x.re)) & + "," & + to_string(to_integer(x.im)) & + ")" ; + end function ; + + subtype c18_t is cx_t( re(17 downto 0), im(17 downto 0) ); + + type c18s_t is array(natural range <>) of c18_t ; + + function sincos(n : positive) return c18s_t is + variable rv : c18s_t(0 to n-1) ; + begin + for idx in 0 to n-1 loop + rv(idx).re := to_signed(integer(round(32768.0*cos(2.0*MATH_PI*real(idx)/real(n)))), 18) ; + rv(idX).im := to_signed(integer(round(32768.0*sin(2.0*MATH_PI*real(idx)/real(n)))), 18) ; + end loop ; + return rv ; + end function ; + + constant sincos_lut : c18s_t(0 to LUT_DEPTH-1) := sincos(LUT_DEPTH) ; + +begin + + tb : process + variable l : line ; + begin + for idx in sincos_lut'range loop + write(l, to_string(sincos_lut(idx))) ; + writeline(output, l) ; + end loop ; + std.env.stop ; + end process ; + +end architecture ; diff --git a/test/regress/testlist.txt b/test/regress/testlist.txt index 1b0d8625f..0d798e74f 100644 --- a/test/regress/testlist.txt +++ b/test/regress/testlist.txt @@ -713,3 +713,4 @@ cmdline5 shell issue603 normal issue609 normal issue618 normal,gA='1',gB='0' +issue615 normal,gold,2008