From 4a7500e56d502cf3f9d729d690795a8658b2d6e0 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Wed, 17 Jan 2024 20:42:32 +0000 Subject: [PATCH] Check prefix of indexed or slice name is a name or function call Fixes #835 --- NEWS.md | 2 ++ src/sem.c | 48 ++++++++++++++++++++++++++++++++++++++-------- test/sem/array.vhd | 17 ++++++++++++++++ test/test_sem.c | 7 +++++-- 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/NEWS.md b/NEWS.md index 132ec3fc..bf3f0310 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,6 +6,8 @@ disconnection specifications (#829). - The `--std` option now controls which VHDL standard the `--install` command uses to compile third-party libraries (#836). +- The prefix of an indexed or slice name now must be another name or + function call, as required by the LRM (#835). ## Version 1.11.2 - 2024-01-04 - Fixed an incorrect length check in the equivalent process for diff --git a/src/sem.c b/src/sem.c index 68d27be4..834b7020 100644 --- a/src/sem.c +++ b/src/sem.c @@ -3717,12 +3717,45 @@ static bool sem_check_ref(tree_t t, nametab_t *tab) return true; } -static bool sem_check_record_ref(tree_t t, nametab_t *tab) +static bool sem_check_name_prefix(tree_t t, nametab_t *tab, const char *what) { tree_t value = tree_value(t); if (!sem_check(value, tab)) return false; + // The prefix of a name may only be function call or another name + switch (tree_kind(value)) { + case T_FCALL: + case T_PROT_FCALL: + case T_REF: + case T_ATTR_REF: + case T_ALL: + case T_ARRAY_REF: + case T_ARRAY_SLICE: + case T_RECORD_REF: + case T_EXTERNAL_NAME: + break; + + default: + { + diag_t *d = diag_new(DIAG_ERROR, tree_loc(t)); + diag_printf(d, "the prefix of %s must be a name or a " + "function call", what); + diag_lrm(d, STD_08, "8.1"); + diag_emit(d); + return false; + } + } + + return true; +} + +static bool sem_check_record_ref(tree_t t, nametab_t *tab) +{ + if (!sem_check_name_prefix(t, tab, "a selected name")) + return false; + + tree_t value = tree_value(t); type_t value_type = tree_type(value); if (type_is_none(value_type)) @@ -3737,8 +3770,7 @@ static bool sem_check_record_ref(tree_t t, nametab_t *tab) static bool sem_check_array_ref(tree_t t, nametab_t *tab) { - tree_t value = tree_value(t); - if (!sem_check(value, tab)) + if (!sem_check_name_prefix(t, tab, "an indexed name")) return false; type_t type = tree_type(tree_value(t)); @@ -3750,8 +3782,8 @@ static bool sem_check_array_ref(tree_t t, nametab_t *tab) const int nparams = tree_params(t); if (nparams != nindex) - sem_error(t, "array %s has %d dimensions but %d indices given", - istr(tree_ident(value)), nindex, nparams); + sem_error(t, "prefix of indexed name has %d dimensions but %d " + "indices given", nindex, nparams); bool ok = true; for (int i = 0; i < nparams; i++) { @@ -3775,7 +3807,7 @@ static bool sem_check_array_ref(tree_t t, nametab_t *tab) static bool sem_check_array_slice(tree_t t, nametab_t *tab) { - if (!sem_check(tree_value(t), tab)) + if (!sem_check_name_prefix(t, tab, "a slice name")) return false; type_t array_type = tree_type(tree_value(t)); @@ -5901,10 +5933,10 @@ static bool sem_check_new(tree_t t, nametab_t *tab) static bool sem_check_all(tree_t t, nametab_t *tab) { - tree_t value = tree_value(t); - if (!sem_check(value, tab)) + if (!sem_check_name_prefix(t, tab, "a selected name")) return false; + tree_t value = tree_value(t); type_t value_type = tree_type(value); if (type_is_none(value_type)) diff --git a/test/sem/array.vhd b/test/sem/array.vhd index 938de997..78ac8798 100644 --- a/test/sem/array.vhd +++ b/test/sem/array.vhd @@ -480,4 +480,21 @@ begin report to_hstring(MY_CONST(0)); -- Error end process; + issue835: process is + type t_my_bv is array (natural range <>) of bit; + variable x : bit_vector(1 to 7); + variable y : t_my_bv(1 to 4); + begin + y(1) := t_my_bv(x)(1); -- Error + y := t_my_bv(x)(1 to 4); -- Error + end process; + + process is + type t_int2d is array (natural range <>, natural range <>) of integer; + type t_int2d_ptr is access t_int2d; + variable p : t_int2d_ptr; + begin + p.all(1) := 2; -- Error + end process; + end architecture; diff --git a/test/test_sem.c b/test/test_sem.c index 90f60c7e..a2e06a0f 100644 --- a/test/test_sem.c +++ b/test/test_sem.c @@ -433,8 +433,8 @@ START_TEST(test_array) { 55, "type of value universal_integer does not match type of" }, { 57, "type of value INT_ARRAY does not match type" }, { 65, "operator \"=\" [INT_ARRAY, TEN_INTS return BOOLEAN]" }, - { 88, "array W has 2 dimensions but 1 indices given" }, - { 89, "array W has 2 dimensions but 3 indices given" }, + { 88, "prefix of indexed name has 2 dimensions but 1 indices given" }, + { 89, "prefix of indexed name has 2 dimensions but 3 indices given" }, { 98, "type of index universal_integer does not match type" }, { 102, "named and positional associations cannot be mixed in" }, { 111, "a choice that is not locally static is allowed" }, @@ -476,6 +476,9 @@ START_TEST(test_array) { 442, "dimension index 5 out of range for type INT_ARRAY" }, { 446, "no visible declaration for FOO" }, { 480, "cannot index non-array type MY_RECORD" }, + { 488, "the prefix of an indexed name must be a name or a function" }, + { 489, "the prefix of a slice name must be a name or a function call" }, + { 497, "prefix of indexed name has 2 dimensions but 1 indices given" }, { -1, NULL } }; expect_errors(expect); -- 2.39.2