Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Correct rules for locally static expressions

  • Loading branch information...
commit 648f70d1f9fcfb72de4f50598196f63c6bc24dec 1 parent 9a4abe1
@nickg authored
Showing with 94 additions and 26 deletions.
  1. +62 −22 src/sem.c
  2. +26 −0 test/sem/seq.vhd
  3. +6 −4 test/test_sem.c
View
84 src/sem.c
@@ -3091,36 +3091,76 @@ static bool sem_check_if(tree_t t)
return ok;
}
-static void sem_locally_static_fn(tree_t t, void *context)
+static bool sem_locally_static(tree_t t)
{
- bool *locally_static = context;
-
// Rules for locally static expressions are in LRM 93 7.4.1
- // TODO: these are not implemented correctly
- if (tree_kind(t) == T_LITERAL)
- return;
- else if (tree_kind(t) == T_REF) {
+ type_t type = tree_type(t);
+ tree_kind_t kind = tree_kind(t);
+
+ // Any literal other than of type time
+ if (kind == T_LITERAL) {
+ type_t std_time = sem_std_type("TIME");
+ return !type_eq(type, std_time);
+ }
+ else if ((kind == T_REF) && (tree_kind(tree_ref(t)) == T_ENUM_LIT))
+ return true;
+
+ // A constant reference with a locally static value
+ if ((kind == T_REF) && (tree_kind(tree_ref(t)) == T_CONST_DECL))
+ return sem_locally_static(tree_value(tree_ref(t)));
+
+ // An alias of a locally static name
+ if (kind == T_ALIAS)
+ return sem_locally_static(tree_value(t));
+
+ // A function call of an implicit operator with locally static actuals
+ if (kind == T_FCALL) {
tree_t decl = tree_ref(t);
- switch (tree_kind(decl)) {
- case T_CONST_DECL:
- case T_ENUM_LIT:
- return;
- default:
- break;
+ if (tree_attr_str(decl, builtin_i) == NULL)
+ return false;
+
+ bool all_static = true;
+ for (unsigned i = 0; i < tree_params(t); i++) {
+ param_t p = tree_param(t, i);
+ all_static = all_static && sem_locally_static(p.value);
}
+ return all_static;
}
- else if (tree_kind(t) == T_QUALIFIED)
- return;
- *locally_static = false;
-}
+ // TODO: clauses e, f, and g re. attributes
-static bool sem_locally_static(tree_t t)
-{
- bool locally_static = true;
- tree_visit(t, sem_locally_static_fn, &locally_static);
- return locally_static;
+ // A qualified expression whose operand is locally static
+ if (kind == T_QUALIFIED)
+ return sem_locally_static(tree_value(t));
+
+ // A type conversion whose expression is locally static
+ if (kind == T_TYPE_CONV)
+ return sem_locally_static(tree_value(t));
+
+ // Aggregates must have locally static range and all elements
+ // must have locally static values
+ if (kind == T_AGGREGATE) {
+ range_t r = type_dim(type, 0);
+ if (r.kind != RANGE_TO && r.kind != RANGE_DOWNTO)
+ return false;
+
+ if (!sem_locally_static(r.left) || !sem_locally_static(r.right))
+ return false;
+
+ for (unsigned i = 0; i < tree_assocs(t); i++) {
+ assoc_t a = tree_assoc(t, i);
+ if ((a.kind == A_NAMED) && !sem_locally_static(a.name))
+ return false;
+
+ if (!sem_locally_static(a.value))
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
}
static bool sem_check_case(tree_t t)
View
26 test/sem/seq.vhd
@@ -85,6 +85,10 @@ begin
process is
type letter is (A, B, C);
variable l : letter;
+ variable v : bit_vector(0 to 3);
+ constant k : bit := '1';
+ variable n : bit;
+ variable i : integer;
begin
l := A;
case l is -- OK
@@ -110,6 +114,28 @@ begin
null;
when others =>
end case;
+ case v is
+ when "0101" => --OK
+ null;
+ when "1101" => -- OK
+ null;
+ end case;
+ case v is
+ when (0 to 3 => k) => -- OK
+ null;
+ when (0 to 3 => n) => -- Not locally static
+ null;
+ end case;
+ case i is
+ when 1 => -- OK
+ null;
+ when integer'(5) => -- OK
+ null;
+ when (1 + 5) * 7 => -- OK
+ null;
+ when i + 2 => -- Not locally static
+ null;
+ end case;
end process;
-- Exit
View
10 test/test_sem.c
@@ -629,10 +629,12 @@ START_TEST(test_seq)
{ 62, "return statement not allowed outside subprogram" },
{ 64, "type of loop condition must be STD.STANDARD.BOOLEAN" },
{ 79, "undefined identifier X" },
- { 102, "others choice must appear last" },
- { 109, "case choice must be locally static" },
- { 120, "type of exit condition must be STD.STANDARD.BOOLEAN" },
- { 135, "parameter must be a variable" },
+ { 106, "others choice must appear last" },
+ { 113, "case choice must be locally static" },
+ { 126, "case choice must be locally static" },
+ { 136, "case choice must be locally static" },
+ { 146, "type of exit condition must be STD.STANDARD.BOOLEAN" },
+ { 161, "parameter must be a variable" },
{ -1, NULL }
};
expect_errors(expect);
Please sign in to comment.
Something went wrong with that request. Please try again.