scope escaping
Adam D. Ruppe
destructionator at gmail.com
Thu Feb 6 16:17:05 PST 2014
On Thursday, 6 February 2014 at 23:27:06 UTC, Meta wrote:
> I know very little about compilers, but wouldn't figuring out
> if a variable is being escaped to an outer scope require flow
> anyalysis?
I might be using the word wrong too, but I don't think so. All
the information needed is available right at the assignment point:
int[] a;
void foo() {
scope int[] b;
a = b; // this line is interesting
}
At that line alone, everything we need to know is available. The
compiler currently has this code:
if (e1->op == TOKvar &&
(((VarExp *)e1)->var->storage_class & STCscope) &&
op == TOKassign)
{
error("cannot rebind scope variables");
}
If a was marked scope, it would trigger that. But I don't think
this is a particularly useful check, at least not alone. We could
try this though:
if (
e1->op == TOKvar &&
!(((VarExp *)e1)->var->storage_class & STCscope) &&
e2->op == TOKvar &&
(((VarExp *)e2)->var->storage_class & STCscope) &&
op == TOKassign)
{
error("cannot assign scope variables to non-scope");
}
Now, that line will fail with this error - scope to non-scope is
not allowed.
If we add scope to the a variable, the existing compiler code
will trigger an error
test500.d(41): Error: cannot rebind scope variables
But I don't like that - it is /too/ conservative (although these
two checks together more or less achieve the first step I want).
However, what if we take that check out, can we allow rebinding
but only to the same or lower scopes?
Well, the VarExp->var we have on the left-hand side has info
about the variable's parent.... and we can check that. I'd like
to point out that this is WRONG but I don't know dmd that well
either:
if (
e1->op == TOKvar &&
(((VarExp *)e1)->var->storage_class & STCscope) &&
e2->op == TOKvar &&
(((VarExp *)e2)->var->storage_class & STCscope) &&
op == TOKassign)
{
Declaration* v1 = ((VarExp*)e1)->var;
Declaration* v2 = ((VarExp*)e2)->var;
if(v1->parent != v2->parent)
error("cannot assign scope variable to higher scope");
}
But this prohibits it from passing outside the function. A more
correct check would be to ensure v1 is equal to or a parent of
v2... and using whatever is needed to handle inner scopes inside
a function.
tbh I don't know just what to look at to get the rest of the
scope, but since the compiler can identify what this name
actually refers to somehow, it must know where the declaration
comes from too! I just don't know where exactly to look.
Of course, the tricky part will be structs, but the same basic
idea of the implementation should work (if we can get it working
first for basic assignments).
More information about the Digitalmars-d
mailing list