[dmd-internals] Errors emitted by the optimizer and the as-if rule

David Nadlinger code at klickverbot.at
Sat Aug 18 10:59:56 PDT 2012


Kenji's fix for issue 8339 introduces code which accesses a
void-initialized variable without setting it first:
https://github.com/D-Programming-Language/phobos/commit/4a0546480078d51a0ad4dbf141c71bf818e034ec

I'm aware that it is contained inside an is(typeof()) check, and it
seems like a clever solution to work around the underlying issue.
However, DMD, with the optimizer enabled, would actually refuse to
compile the code (even if a __traits(compiles, …) check returned
true!), because access of uninitialized data is detected during data
flow analysis somewhere in the optimizer, producing a "variable used
before set"-type error.

My point, which is only tangentially related to the bug fix in
question, is that the optimizer in DMD grossly violates the "as-if"
rule by changing the definition of what is legal D code. For example,
the spec [1] says that accessing an uninitialized value results in
undefined behavior. To me, this implies that code like this is fine if
it is never executed. Yet, DMD for example refuses to compile a
function which contains such an access of uninitialized data (or a
null pointer dereference, …), even if that function is never invoked.

In my opinion, this is clearly a bug. We can chose to either make
accessing uninitialized data illegal – but the semantics of this are
difficult to define in the general case due to the requirement of
elaborate data flow analysis, somewhat defeating the point of having
VoidInitializer in the first place –, _or_ to make it undefined
behavior. Right now, we are doing a little of both, which is arguable
the worst solution. It causes unexpected behavior of is(typeof()) and
friends, and, much worse, leads to problems with cross-compiler
compatibility: If a program includes piece of code which uses
uninitialized data is never executed at runtime, it works fine when
compiled GDC and LDC, in perfect agreement with the spec, yet DMD
refuses to accept it.

Yes, emitting a warning if use of uninitialized data is detected is
most likely a good idea, but changing the language semantics depending
on whether the optimizer is enabled is not.

What do you think?

David


[1] http://dlang.org/declaration.html#VoidInitializer


More information about the dmd-internals mailing list