From 42d0a7d554045af108b63ee3a3efb120ff75f3e8 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Tue, 20 Jun 2023 20:14:28 +0100 Subject: [PATCH] Fix crash indexing protected function call that returns an array E.g. P.F(X) where F takes no argument and returns an array. Issue #726 --- src/names.c | 5 ++- src/tree.c | 1 + test/regress/issue726.vhd | 85 +++++++++++++++++++++++++++++++++++++++ test/regress/testlist.txt | 1 + 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 test/regress/issue726.vhd diff --git a/src/names.c b/src/names.c index 86402575..37a6862f 100644 --- a/src/names.c +++ b/src/names.c @@ -3174,12 +3174,15 @@ static type_t solve_fcall(nametab_t *tab, tree_t fcall) && can_call_no_args(tab, decl) && tree_params(fcall) > 0) { - tree_t new = tree_new(T_FCALL); + tree_t new = tree_new(kind); tree_set_ref(new, decl); tree_set_ident(new, tree_ident(fcall)); tree_set_loc(new, tree_loc(fcall)); tree_set_type(new, type); + if (kind == T_PROT_FCALL) + tree_set_name(new, tree_name(fcall)); + tree_change_kind(fcall, T_ARRAY_REF); tree_set_value(fcall, new); diff --git a/src/tree.c b/src/tree.c index 21653712..4e08f1b1 100644 --- a/src/tree.c +++ b/src/tree.c @@ -403,6 +403,7 @@ static const change_allowed_t change_allowed[] = { { T_REF, T_PCALL }, { T_ARRAY_REF, T_FCALL }, { T_FCALL, T_ARRAY_REF }, + { T_PROT_FCALL, T_ARRAY_REF }, { T_DESIGN_UNIT, T_ENTITY }, { T_DESIGN_UNIT, T_PACKAGE }, { T_DESIGN_UNIT, T_PACK_BODY }, diff --git a/test/regress/issue726.vhd b/test/regress/issue726.vhd new file mode 100644 index 00000000..90dc8453 --- /dev/null +++ b/test/regress/issue726.vhd @@ -0,0 +1,85 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +package types_pkg is + type t_slv_array is array (natural range <>) of std_logic_vector; + subtype t_word is std_logic_vector(15 downto 0); + subtype t_word_array is t_slv_array(open)(t_word'range); + subtype t_addr is natural range 1 to 30; + type t_data is array (t_addr) of t_word_array(0 to 31); +end package types_pkg; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.types_pkg.all; + +package protected_pkg is + type t_config_interface is protected + impure function get_val return t_data; + end protected t_config_interface; +end package protected_pkg; +package body protected_pkg is + type t_config_interface is protected body + variable v_data : t_data := (others => (others => (others => '0'))); + impure function get_val return t_data is + begin + return v_data; + end function get_val; + end protected body t_config_interface; +end package body; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.protected_pkg.all; + +package shared_variables_pkg is + shared variable shared_config : t_config_interface; +end package shared_variables_pkg; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.types_pkg.all; +use work.shared_variables_pkg.all; + +package test_pkg is + impure function randomize(constant val : t_word_array) return t_word_array; +end package test_pkg; + +package body test_pkg is + impure function randomize(constant val : t_word_array) return t_word_array is + begin + return val; + end function; +end package body; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.types_pkg.all; +use work.shared_variables_pkg.all; +use work.test_pkg.all; + +entity issue726 is +end entity issue726; + +architecture str of issue726 is +begin + process + variable v_data : t_word_array(0 to 31); + constant C_VAL : unsigned(4 downto 0) := "00010"; + begin + v_data := randomize(shared_config.get_val(to_integer(C_VAL))); + for i in v_data'range loop + assert v_data(i) = X"0000"; + end loop; + wait; + end process; +end architecture; diff --git a/test/regress/testlist.txt b/test/regress/testlist.txt index 588c8eda..ec72727b 100644 --- a/test/regress/testlist.txt +++ b/test/regress/testlist.txt @@ -807,3 +807,4 @@ issue715 shell issue714 normal elab39 shell issue718 normal,gold,2008 +issue726 normal,2008 -- 2.39.2