Skip to content

Commit

Permalink
Fix a regression in aggregate type checking. Fixes xxx
Browse files Browse the repository at this point in the history
  • Loading branch information
nickg committed Jan 18, 2025
1 parent e045208 commit 32b2084
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 21 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
(from @NikLeberg) (#1091).
- Fixed a crash when a constant record aggregate has a null array
element (#1137).
- Fixed a regression that caused some array aggregates to be incorrectly
reported as ambiguous (#1138).

## Version 1.15.0 - 2025-01-11
- `--load` is now a global option and should be placed before the `-r`
Expand Down
46 changes: 25 additions & 21 deletions src/names.c
Original file line number Diff line number Diff line change
Expand Up @@ -4495,16 +4495,13 @@ static type_t solve_array_aggregate(nametab_t *tab, tree_t agg, type_t type)
type_set_push(tab, &ts);

type_t t0, t1 = NULL;
bool composite_elem = false;
const int ndims = dimension_of(type);
if (ndims == 1) {
type_t elem = type_elem(type);
type_set_add(tab, (t0 = elem), NULL);

if (standard() >= STD_08) {
if (standard() >= STD_08)
t1 = type_base_recur(type);
composite_elem = type_is_composite(elem);
}
}
else
t0 = array_aggregate_type(type, 1);
Expand Down Expand Up @@ -4563,30 +4560,37 @@ static type_t solve_array_aggregate(nametab_t *tab, tree_t agg, type_t type)
break;
}

bool allow_slice = t1 != NULL && (kind == A_POS || kind == A_RANGE);

// This seems incorrect according to the 2008 LRM but without it
// many previously legal nested aggregates are ambiguous
tree_t value = tree_value(a);
if (composite_elem && tree_kind(value) == T_AGGREGATE)
allow_slice = false;

// Hack to avoid pushing/popping type set on each iteration
ATRIM(tab->top_type_set->members, 0);
type_set_add(tab, t0, NULL);
if (allow_slice)
type_set_add(tab, t1, NULL);

type_t etype = _solve_types(tab, value);
tree_t value = tree_value(a);

if (allow_slice && type_eq(etype, t1)) {
// VHDL-2008 slice in aggregate
switch (kind) {
case A_RANGE: tree_set_subkind(a, A_SLICE); break;
case A_POS: tree_set_subkind(a, A_CONCAT); break;
default: break;
if (t1 != NULL && (kind == A_POS || kind == A_RANGE)) {
// In the 2008 LRM the value may have the same type as the
// aggregate it which case it behaves as a concatentation.
// However we only choose this interpretation if the aggregate
// would be illegal without it, as otherwise many previously
// legal nested aggregates are ambiguous.
type_t etype;
if (is_unambiguous(value))
etype = _solve_types(tab, value);
else if ((etype = try_solve_type(tab, value)) == NULL) {
type_set_add(tab, t1, NULL);
etype = _solve_types(tab, value);
}

if (type_eq(etype, t1)) {
// VHDL-2008 slice in aggregate
switch (kind) {
case A_RANGE: tree_set_subkind(a, A_SLICE); break;
case A_POS: tree_set_subkind(a, A_CONCAT); break;
default: should_not_reach_here();
}
}
}
else
_solve_types(tab, value);
}

type_set_pop(tab, &ts);
Expand Down
17 changes: 17 additions & 0 deletions test/parse/issue1138.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
entity test is
end entity test;

architecture rtl of test is

subtype slv64_type is bit_vector(0 to 63);
type slv64_array_type is array (natural range <>) of slv64_type;

constant zeroes : bit_vector(0 to 31) := x"00000000";
constant more_zeroes : bit_vector(0 to 31) := x"00000000";

-- doesn't work in nvc 1.15.0, works in nvc 1.14.2
-- error: ambiguous use of operator "&"
constant test_constant : slv64_array_type := (zeroes & more_zeroes, zeroes & more_zeroes);

begin
end architecture rtl;
15 changes: 15 additions & 0 deletions test/test_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -7204,6 +7204,20 @@ START_TEST(test_issue1129)
}
END_TEST

START_TEST(test_issue1138)
{
set_standard(STD_08);

input_from_file(TESTDIR "/parse/issue1138.vhd");

parse_and_check(T_ENTITY, T_ARCH);

fail_unless(parse() == NULL);

fail_if_errors();
}
END_TEST

Suite *get_parse_tests(void)
{
Suite *s = suite_create("parse");
Expand Down Expand Up @@ -7382,6 +7396,7 @@ Suite *get_parse_tests(void)
tcase_add_test(tc_core, test_aggregate2);
tcase_add_test(tc_core, test_issue1124);
tcase_add_test(tc_core, test_issue1129);
tcase_add_test(tc_core, test_issue1138);
suite_add_tcase(s, tc_core);

return s;
Expand Down

0 comments on commit 32b2084

Please sign in to comment.