Skip to content

Commit 5b805da

Browse files
committed
Fixes to handling of staticness of generics and constants
Fixes #1022
1 parent 4dcff16 commit 5b805da

File tree

7 files changed

+87
-31
lines changed

7 files changed

+87
-31
lines changed

src/common.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1712,7 +1712,7 @@ static bool is_static(tree_t expr)
17121712
tree_t decl = tree_ref(expr);
17131713
switch (tree_kind(decl)) {
17141714
case T_CONST_DECL:
1715-
return !(tree_flags(decl) & TREE_F_SEQ_BLOCK);
1715+
return !!(tree_flags(decl) & TREE_F_GLOBALLY_STATIC);
17161716
case T_UNIT_DECL:
17171717
case T_ENUM_LIT:
17181718
case T_GENERIC_DECL:

src/parse.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4997,6 +4997,20 @@ static void p_interface_constant_declaration(tree_t parent, tree_kind_t kind,
49974997
if ((mode == PORT_OUT || mode == PORT_INOUT) && !explicit_constant)
49984998
class = C_VARIABLE;
49994999

5000+
if (kind == T_GENERIC_DECL) {
5001+
// In the 2008 standard generics in packages or subprograms are
5002+
// locally static if they have a locally static subtype
5003+
switch (tree_kind(parent)) {
5004+
case T_PACKAGE:
5005+
case T_FUNC_DECL:
5006+
case T_PROC_DECL:
5007+
flags |= TREE_F_LOCALLY_STATIC;
5008+
break;
5009+
default:
5010+
break;
5011+
}
5012+
}
5013+
50005014
type_t type = p_interface_type_indication(parent);
50015015

50025016
tree_t init = NULL;
@@ -6919,12 +6933,33 @@ static void p_constant_declaration(tree_t parent)
69196933
solve_known_subtype(nametab, init, type);
69206934
}
69216935

6936+
// According to the LRM all constants are globally static but that
6937+
// leads to a number of logical inconsistencies so we retrict to only
6938+
// constants in certain regions where the value can be computed
6939+
// during elaboration
6940+
tree_flags_t flags = 0;
6941+
switch (tree_kind(parent)) {
6942+
case T_ENTITY:
6943+
case T_ARCH:
6944+
case T_PACKAGE:
6945+
case T_PACK_BODY:
6946+
case T_BLOCK:
6947+
case T_FOR_GENERATE:
6948+
case T_COND_STMT: // If-generate
6949+
case T_ALTERNATIVE: // For-generate
6950+
flags |= TREE_F_GLOBALLY_STATIC;
6951+
break;
6952+
default:
6953+
break;
6954+
}
6955+
69226956
consume(tSEMI);
69236957

69246958
for (ident_list_t *it = ids; it != NULL; it = it->next) {
69256959
tree_t t = tree_new(T_CONST_DECL);
69266960
tree_set_ident(t, it->ident);
69276961
tree_set_type(t, type);
6962+
tree_set_flag(t, flags);
69286963
tree_set_loc(t, &(it->loc));
69296964
if (init != NULL)
69306965
tree_set_value(t, init);

src/sem.c

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,18 @@ static bool sem_check_const_decl(tree_t t, nametab_t *tab)
970970

971971
if (fwd == NULL)
972972
sem_propagate_constraints(t, value);
973+
974+
// A constant with a globaly static value should be treated as
975+
// globally static regardless of where it is declared
976+
if (sem_globally_static(value)) {
977+
tree_set_flag(t, TREE_F_GLOBALLY_STATIC);
978+
979+
// A reference to a constant with a locally static subype and
980+
// locally static value is locally static
981+
if (sem_locally_static(value)
982+
&& sem_static_subtype(tree_type(t), sem_locally_static))
983+
tree_set_flag(t, TREE_F_LOCALLY_STATIC);
984+
}
973985
}
974986
else if (tree_kind(find_enclosing(tab, S_DESIGN_UNIT)) != T_PACKAGE)
975987
sem_error(t, "deferred constant declarations are only permitted "
@@ -1447,6 +1459,13 @@ static bool sem_check_generic_decl(tree_t t, nametab_t *tab)
14471459
type_pp(type));
14481460
}
14491461

1462+
if (tree_flags(t) & TREE_F_LOCALLY_STATIC) {
1463+
// For a generic declaration in a pacakage or subprogram to be
1464+
// locally static it must also have a locally static subtype
1465+
if (!sem_static_subtype(type, sem_locally_static))
1466+
tree_clear_flag(t, TREE_F_LOCALLY_STATIC);
1467+
}
1468+
14501469
return true;
14511470
}
14521471

@@ -5530,20 +5549,17 @@ static bool sem_locally_static(tree_t t)
55305549

55315550
// A constant reference (other than a deferred constant) with a
55325551
// locally static value
5533-
if (dkind == T_CONST_DECL) {
5534-
if (tree_has_value(decl))
5535-
return sem_locally_static(tree_value(decl));
5536-
else
5537-
return false;
5538-
}
5552+
if (dkind == T_CONST_DECL && (tree_flags(decl) & TREE_F_LOCALLY_STATIC))
5553+
return true;
55395554

55405555
// An alias of a locally static name
55415556
if (dkind == T_ALIAS)
55425557
return sem_locally_static(tree_value(decl));
55435558

5544-
// [2008] A generic reference with a locally static subtype
5545-
if (dkind == T_GENERIC_DECL && (standard() >= STD_08 || relaxed_rules()))
5546-
return sem_static_subtype(tree_type(decl), sem_locally_static);
5559+
// [2008] A formal generic constant of a generic-mapped subprogram
5560+
// or package with a locally static subtype
5561+
if (dkind == T_GENERIC_DECL && (tree_flags(decl) & TREE_F_LOCALLY_STATIC))
5562+
return true;
55475563
}
55485564

55495565
// A locally static range
@@ -5794,8 +5810,16 @@ static bool sem_globally_static(tree_t t)
57945810

57955811
if (kind == T_REF) {
57965812
tree_t decl = tree_ref(t);
5797-
const tree_kind_t decl_kind = tree_kind(decl);
5798-
return decl_kind == T_GENERIC_DECL || decl_kind == T_CONST_DECL;
5813+
switch (tree_kind(decl)) {
5814+
case T_GENERIC_DECL:
5815+
return true;
5816+
case T_CONST_DECL:
5817+
// Do not treat all constants as globally static, this is a
5818+
// defect in the LRM
5819+
return !!(tree_flags(decl) & TREE_F_GLOBALLY_STATIC);
5820+
default:
5821+
return false;
5822+
}
57995823
}
58005824
else if (kind == T_EXTERNAL_NAME)
58015825
return tree_class(t) == C_CONSTANT;
@@ -7157,20 +7181,6 @@ static bool sem_check_cond_value(tree_t t, nametab_t *tab)
71577181
return true;
71587182
}
71597183

7160-
static bool sem_check_sequence(tree_t t, nametab_t *tab)
7161-
{
7162-
const int ndecls = tree_decls(t);
7163-
for (int i = 0; i < ndecls; i++) {
7164-
// Mark all constant declarations as they need to be treated
7165-
// specially when calculating longest static prefix
7166-
tree_t d = tree_decl(t, i);
7167-
if (tree_kind(d) == T_CONST_DECL)
7168-
tree_set_flag(d, TREE_F_SEQ_BLOCK);
7169-
}
7170-
7171-
return true;
7172-
}
7173-
71747184
static bool sem_check_prot_decl(tree_t t, nametab_t *tab)
71757185
{
71767186
const int ndecls = tree_decls(t);
@@ -7349,6 +7359,7 @@ bool sem_check(tree_t t, nametab_t *tab)
73497359
case T_BOX:
73507360
case T_PSL:
73517361
case T_LOOP:
7362+
case T_SEQUENCE:
73527363
return true;
73537364
case T_CONV_FUNC:
73547365
return sem_check_conv_func(t, tab);
@@ -7374,8 +7385,6 @@ bool sem_check(tree_t t, nametab_t *tab)
73747385
return sem_check_view_decl(t, tab);
73757386
case T_COND_VALUE:
73767387
return sem_check_cond_value(t, tab);
7377-
case T_SEQUENCE:
7378-
return sem_check_sequence(t, tab);
73797388
case T_PROT_DECL:
73807389
return sem_check_prot_decl(t, tab);
73817390
case T_INERTIAL:

src/tree.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,6 @@ typedef enum {
422422
TREE_F_IMPURE_FILE = (1 << 22),
423423
TREE_F_IMPURE_SHARED = (1 << 23),
424424
TREE_F_CALL_NO_ARGS = (1 << 24),
425-
TREE_F_SEQ_BLOCK = (1 << 25),
426425
} tree_flags_t;
427426

428427
typedef enum {

test/sem/issue105.vhd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ begin
99
process (x) is
1010
begin
1111
case x is
12-
when GEN => -- OK in 2008
12+
when GEN => -- Error (used to be allowed)
1313
report "x = GEN";
1414
when others =>
1515
report "x /= GEN";

test/sem/static.vhd

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,11 @@ begin
115115
end case;
116116
end process;
117117

118+
p4: process is
119+
constant N1 : integer := N + 1;
120+
variable v : bit_vector(7 downto 0);
121+
alias a is v(N1 downto 0); -- OK
122+
begin
123+
end process;
124+
118125
end architecture;

test/test_sem.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1316,11 +1316,17 @@ START_TEST(test_issue105)
13161316
{
13171317
set_standard(STD_08);
13181318

1319+
const error_t expect[] = {
1320+
{ 12, "case choice must be locally static" },
1321+
{ -1, NULL }
1322+
};
1323+
expect_errors(expect);
1324+
13191325
input_from_file(TESTDIR "/sem/issue105.vhd");
13201326

13211327
parse_and_check(T_ENTITY, T_ARCH, T_ENTITY, T_ARCH);
13221328

1323-
fail_if_errors();
1329+
check_expected_errors();
13241330
}
13251331
END_TEST
13261332

0 commit comments

Comments
 (0)