From 1fbb59c03c03b7a63fbd5e8ce084e34b3ecaf9f6 Mon Sep 17 00:00:00 2001 From: "ben.franksen" <ben.franksen@online.de> Date: Tue, 12 Apr 2011 16:00:24 +0000 Subject: [PATCH] snc,test: reject badly scoped assign/monitor/sync/syncq Also added a test for this and removed item from TODO list. --- TODO | 5 ----- src/snc/analysis.c | 35 +++++++++++++++++++++++++++++++---- test/validate/Makefile | 2 ++ test/validate/scope.st | 20 ++++++++++++++++++++ test/validate/syncq.st | 2 +- 5 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 test/validate/scope.st diff --git a/TODO b/TODO index eb1ade6e..7ba4a114 100644 --- a/TODO +++ b/TODO @@ -47,8 +47,3 @@ has been connected to separate PVs. Currently this puts/gets the first element, but wouldn't it be nice if it meant to put/get all (connected) elements? Write to tech-talk and ask (since it breaks compatibility)? - -* What if a variable is declared in a outer scope (e.g. global), but - the "monitor" or "sync" appears in an inner scope? The compiler currently - allows this but there is no well-defined semantics I can think of. - Need to fix the compiler to abort with an error in this case. diff --git a/src/snc/analysis.c b/src/snc/analysis.c index f6151137..91831d61 100644 --- a/src/snc/analysis.c +++ b/src/snc/analysis.c @@ -306,13 +306,20 @@ static void analyse_assign(SymTable st, ChanList *chan_list, Expr *scope, Expr * assert(defn->type == D_ASSIGN); if (!vp) { - error_at_expr(defn, "variable '%s' not declared\n", name); + error_at_expr(defn, "cannot assign variable '%s': " + "variable was not declared\n", name); return; } assert(vp->type); if (!type_assignable(vp->type)) { - error_at_expr(defn, "this type of variable cannot be assigned to a pv\n", name); + error_at_expr(defn, "cannot assign variable '%s': wrong type\n", name); + return; + } + if (vp->scope != scope) + { + error_at_expr(defn, "cannot assign variable '%s': " + "assign must be in the same scope as declaration\n", name); return; } if (defn->assign_subscr) @@ -497,7 +504,7 @@ static void monitor_var(Expr *defn, Var *vp) if (vp->assign == M_NONE) { - error_at_expr(defn, "variable '%s' not assigned\n", vp->name); + error_at_expr(defn, "cannot monitor variable '%s': not assigned\n", vp->name); return; } if (vp->monitor == M_SINGLE) @@ -596,7 +603,13 @@ static void analyse_monitor(SymTable st, Expr *scope, Expr *defn) if (!vp) { error_at_expr(defn, - "variable '%s' not declared\n", var_name); + "cannot monitor variable '%s': not declared\n", var_name); + return; + } + if (vp->scope != scope) + { + error_at_expr(defn, "cannot monitor variable '%s': " + "monitor must be in the same scope as declaration\n", var_name); return; } if (defn->monitor_subscr) @@ -737,6 +750,13 @@ static void analyse_sync(SymTable st, Expr *scope, Expr *defn) error_at_expr(defn, "variable '%s' not declared\n", var_name); return; } + if (vp->scope != scope) + { + error_at_expr(defn, "cannot sync variable '%s' to event flag '%s': " + "sync must be in the same scope as (variable) declaration\n", + var_name, ef_name); + return; + } if (vp->sync == M_SINGLE) { error_at_expr(defn, "variable '%s' already sync'd\n", vp->name); @@ -893,6 +913,13 @@ static void analyse_syncq(SymTable st, SyncQList *syncq_list, Expr *scope, Expr error_at_expr(defn, "variable '%s' not declared\n", var_name); return; } + if (vp->scope != scope) + { + error_at_expr(defn, "cannot syncq variable '%s' to event flag '%s': " + "sync must be in the same scope as (variable) declaration\n", + var_name, ef_name); + return; + } if (vp->syncq == M_SINGLE) { error_at_expr(defn, "variable '%s' already syncq'd\n", vp->name); diff --git a/test/validate/Makefile b/test/validate/Makefile index 72d298cc..d2897520 100644 --- a/test/validate/Makefile +++ b/test/validate/Makefile @@ -15,6 +15,8 @@ TESTPROD += declarations TESTPROD += local TESTPROD += pvPutAsync TESTPROD += pvSync +#compiler test, should fail with errors +#TESTPROD += scope TESTPROD += sncDelay TESTPROD += sncEntry TESTPROD += sncEntryOpte diff --git a/test/validate/scope.st b/test/validate/scope.st new file mode 100644 index 00000000..ac4e8b9b --- /dev/null +++ b/test/validate/scope.st @@ -0,0 +1,20 @@ +program scope + +int i, j; +evflag f, g, h; + +ss start { + assign i; + monitor i; + sync i to f; + syncq i to f; + int k; + state first { + assign j; + monitor j; + sync j to g; + syncq k to h; + when () { + } exit + } +} diff --git a/test/validate/syncq.st b/test/validate/syncq.st index 4147db6d..b7ccafba 100644 --- a/test/validate/syncq.st +++ b/test/validate/syncq.st @@ -23,6 +23,7 @@ syncq x to ef_x; int n = 0; assign n; +monitor n; ss get { state get { @@ -62,7 +63,6 @@ ss put { } ss flush { - monitor n; state idle { when (n%20==0) { printf("flush\n"); -- GitLab