September 15, 2012
As far as I understand, Expression::apply is meant to iterate over any and all of the subexpressions "contained" in an Expression. This is the way it is used, for example, in Expression::toDelegate to determine the variables referenced from lazy arguments that are turned into delegates.

The problem is that apply doesn't take DeclarationExps into account, which can also contain expressions (e.g. in form of a VarDeclaration initializer).

A problem caused by this occurs with lazy parameters of a type with a
postblit, for which a temporary is internally declared via a rewrite
to a comma expression containing a variable declaration wrapped in a
Declaration. If the parameter is a variable in the outer scope, this
actually leads to the nested reference to it not being detected. For a
test case and a quick-and-dirty workaround, see
https://github.com/ldc-developers/ldc/blob/master/dmd2/delegatize.c#L117
(the example in question actually seems to work fine with DMD, but I
don't think it would be hard to come up with a test case where a
closure would be needed, but is not allocated due to this).

The above is obviously only a quick hack to fix this very specific case for LDC, but I'm not sure what the correct solution for the problem is. At first, I tried to implement the VarDeclaration->ExpInitializer check in a new DeclarationExp::apply, but it lead to a bunch of "not available at compile time" errors in CTFE.

Could somebody confirm what the intended behavior of Expression::apply is? If DeclarationExps should be taken into account in the general, I could submit a pull request for that and work with Don to investigate the CTFE errors, but I'm not 100% sure that this is really an oversight.

David
_______________________________________________
dmd-internals mailing list
dmd-internals@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-internals

November 03, 2012
Ping? I added a similar test case which also produces wrong code with DMD to Bugzilla: http://d.puremagic.com/issues/show_bug.cgi?id=8957

David


On Sat, Sep 15, 2012 at 9:26 PM, David Nadlinger <code@klickverbot.at>wrote:

> As far as I understand, Expression::apply is meant to iterate over any and all of the subexpressions "contained" in an Expression. This is the way it is used, for example, in Expression::toDelegate to determine the variables referenced from lazy arguments that are turned into delegates.
>
> The problem is that apply doesn't take DeclarationExps into account, which can also contain expressions (e.g. in form of a VarDeclaration initializer).
>
> A problem caused by this occurs with lazy parameters of a type with a
> postblit, for which a temporary is internally declared via a rewrite
> to a comma expression containing a variable declaration wrapped in a
> Declaration. If the parameter is a variable in the outer scope, this
> actually leads to the nested reference to it not being detected. For a
> test case and a quick-and-dirty workaround, see
> https://github.com/ldc-developers/ldc/blob/master/dmd2/delegatize.c#L117
> (the example in question actually seems to work fine with DMD, but I
> don't think it would be hard to come up with a test case where a
> closure would be needed, but is not allocated due to this).
>
> The above is obviously only a quick hack to fix this very specific case for LDC, but I'm not sure what the correct solution for the problem is. At first, I tried to implement the VarDeclaration->ExpInitializer check in a new DeclarationExp::apply, but it lead to a bunch of "not available at compile time" errors in CTFE.
>
> Could somebody confirm what the intended behavior of Expression::apply is? If DeclarationExps should be taken into account in the general, I could submit a pull request for that and work with Don to investigate the CTFE errors, but I'm not 100% sure that this is really an oversight.
>
> David
>