diff --git a/src/lower.c b/src/lower.c index d1e86f3ef..3daa098bb 100644 --- a/src/lower.c +++ b/src/lower.c @@ -7497,11 +7497,19 @@ static void lower_sub_signals(lower_unit_t *lu, type_t type, type_t var_type, field_reg = emit_load_indirect(field_reg); } + vcode_reg_t fbounds_reg = VCODE_INVALID_REG; + if (bounds_reg != VCODE_INVALID_REG) { + fbounds_reg = emit_record_ref(bounds_reg, i); + + if (have_uarray_ptr(fbounds_reg)) + fbounds_reg = emit_load_indirect(fbounds_reg); + } + vcode_reg_t ptr_reg = emit_record_ref(sig_ptr, i); lower_sub_signals(lu, et, ft, ft, f, fview, VCODE_INVALID_VAR, ptr_reg, field_reg, resolution, null_field_reg, newflags, - VCODE_INVALID_REG); + fbounds_reg); } emit_pop_scope(); @@ -7526,13 +7534,19 @@ static void lower_signal_decl(lower_unit_t *lu, tree_t decl) init_reg = lower_known_subtype(lu, value, type, VCODE_INVALID_REG); } + vcode_reg_t bounds_reg = VCODE_INVALID_REG; + if (standard() >= STD_19 && type_is_unconstrained(type)) { + type = value_type; + bounds_reg = init_reg; + } + sig_flags_t flags = 0; if (tree_flags(decl) & TREE_F_REGISTER) flags |= NET_F_REGISTER; lower_sub_signals(lu, type, type, value_type, decl, NULL, var, VCODE_INVALID_REG, init_reg, VCODE_INVALID_REG, - VCODE_INVALID_REG, flags, VCODE_INVALID_REG); + VCODE_INVALID_REG, flags, bounds_reg); if (cover_enabled(lu->cover, COVER_MASK_TOGGLE)) lower_toggle_coverage(lu, decl); diff --git a/src/sem.c b/src/sem.c index 6b75ead1f..21307405c 100644 --- a/src/sem.c +++ b/src/sem.c @@ -981,12 +981,23 @@ static bool sem_check_signal_decl(tree_t t, nametab_t *tab) return false; if (type_is_unconstrained(type)) { - diag_t *d = diag_new(DIAG_ERROR, tree_loc(t)); - diag_printf(d, "declaration of signal %s cannot have unconstrained " - "type %s", istr(tree_ident(t)), type_pp(type)); - sem_unconstrained_decl_hint(d, type); - diag_emit(d); - return false; + if (standard() < STD_19) { + diag_t *d = diag_new(DIAG_ERROR, tree_loc(t)); + diag_printf(d, "declaration of signal %s cannot have unconstrained " + "type %s", istr(tree_ident(t)), type_pp(type)); + sem_unconstrained_decl_hint(d, type); + diag_emit(d); + return false; + } + else if (!tree_has_value(t)) { + diag_t *d = diag_new(DIAG_ERROR, tree_loc(t)); + diag_printf(d, "declaration of signal %s without an initial value " + "cannot have unconstrained type %s", + istr(tree_ident(t)), type_pp(type)); + sem_unconstrained_decl_hint(d, type); + diag_emit(d); + return false; + } } else if (type_is_incomplete(type)) sem_error(t, "declaration of signal %s cannot have incomplete type %s", @@ -1022,12 +1033,23 @@ static bool sem_check_var_decl(tree_t t, nametab_t *tab) return false; if (type_is_unconstrained(type)) { - diag_t *d = diag_new(DIAG_ERROR, tree_loc(t)); - diag_printf(d, "declaration of variable %s cannot have unconstrained " - "type %s", istr(tree_ident(t)), type_pp(type)); - sem_unconstrained_decl_hint(d, type); - diag_emit(d); - return false; + if (standard() < STD_19) { + diag_t *d = diag_new(DIAG_ERROR, tree_loc(t)); + diag_printf(d, "declaration of variable %s cannot have unconstrained " + "type %s", istr(tree_ident(t)), type_pp(type)); + sem_unconstrained_decl_hint(d, type); + diag_emit(d); + return false; + } + else if (!tree_has_value(t)) { + diag_t *d = diag_new(DIAG_ERROR, tree_loc(t)); + diag_printf(d, "declaration of variable %s without an initial value " + "cannot have unconstrained type %s", istr(tree_ident(t)), + type_pp(type)); + sem_unconstrained_decl_hint(d, type); + diag_emit(d); + return false; + } } else if (type_is_incomplete(type)) sem_error(t, "declaration of variable %s cannot have incomplete type %s", diff --git a/test/regress/signal32.vhd b/test/regress/signal32.vhd new file mode 100644 index 000000000..63185c31f --- /dev/null +++ b/test/regress/signal32.vhd @@ -0,0 +1,40 @@ +-- LCS 2016-019 +entity signal32 is +end entity; + +architecture test of signal32 is + type rec_t is record + x : integer_vector; + end record; + + function get_rec return rec_t is + begin + return (x => (5, 6)); + end function; + + signal s1 : integer_vector := (1, 2, 3); + signal s2 : rec_t := get_rec; +begin + + p1: process is + variable v1 : integer_vector := (1, 2, 3); + variable v2 : rec_t := get_rec; + begin + assert s1'length = 3; + assert s1'left = 0; + assert s1(1) = 2; + s1(2) <= 5; + wait for 1 ns; + assert s1 = (1, 2, 5); + assert v1'length = 3; + assert v1(2) = 3; + assert s2.x'length = 2; + assert s2.x = (5, 6); + assert v2.x'length = 2; + assert v2.x = (5, 6); + v2.x(1) := 9; + assert v2.x = (5, 9); + wait; + end process; + +end architecture; diff --git a/test/regress/testlist.txt b/test/regress/testlist.txt index 6c2833fad..05b770317 100644 --- a/test/regress/testlist.txt +++ b/test/regress/testlist.txt @@ -812,3 +812,4 @@ issue724 normal,2019 issue653 normal,2008 protected10 normal,2019 reflect1 normal,2019 +signal32 normal,2019 diff --git a/test/sem/lcs2016_19.vhd b/test/sem/lcs2016_19.vhd new file mode 100644 index 000000000..1cc2b3a11 --- /dev/null +++ b/test/sem/lcs2016_19.vhd @@ -0,0 +1,16 @@ +entity lcs2016_19 is +end entity; + +architecture test of lcs2016_19 is + signal s1 : integer_vector := (1, 2, 3); -- OK + signal s2 : integer_vector; -- Error +begin + + p1: process is + variable v1 : integer_vector := (1, 2, 3); -- OK + variable v2 : integer_vector; -- Error + begin + wait; + end process; + +end architecture; diff --git a/test/test_sem.c b/test/test_sem.c index 356e9ab3b..7940513d9 100644 --- a/test/test_sem.c +++ b/test/test_sem.c @@ -3209,6 +3209,27 @@ START_TEST(test_lcs2016_14a) } END_TEST +START_TEST(test_lcs2016_19) +{ + set_standard(STD_19); + + input_from_file(TESTDIR "/sem/lcs2016_19.vhd"); + + const error_t expect[] = { + { 6, "declaration of signal S2 without an initial value cannot " + "have unconstrained type INTEGER_VECTOR" }, + { 11, "declaration of variable V2 without an initial value cannot " + "have unconstrained type INTEGER_VECTOR" }, + { -1, NULL } + }; + expect_errors(expect); + + parse_and_check(T_ENTITY, T_ARCH); + + check_expected_errors(); +} +END_TEST + Suite *get_sem_tests(void) { Suite *s = suite_create("sem"); @@ -3361,6 +3382,7 @@ Suite *get_sem_tests(void) tcase_add_test(tc_core, test_issue713); tcase_add_test(tc_core, test_lcs2016_41); tcase_add_test(tc_core, test_lcs2016_14a); + tcase_add_test(tc_core, test_lcs2016_19); suite_add_tcase(s, tc_core); return s; diff --git a/www/features.html.in b/www/features.html.in index 7cf330841..e53032a4a 100644 --- a/www/features.html.in +++ b/www/features.html.in @@ -238,7 +238,7 @@ table below. LCS2016-019 Inferring constraints from initial values for signals and variables - + master