[dmd-internals] Expression::apply, DeclarationExp and a possible nested context bug

David Nadlinger code at klickverbot.at
Sat Sep 15 12:26:59 PDT 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


More information about the dmd-internals mailing list