Fixing spurious "statement is not reachable" in template code
tsbockman via Digitalmars-d
digitalmars-d at puremagic.com
Sat Oct 24 10:25:21 PDT 2015
While improving the DMD front-end's constant folding:
https://github.com/D-Programming-Language/dmd/pull/5229
I found out about DMD issue 14835:
https://issues.dlang.org/show_bug.cgi?id=14835
Briefly:
///////////////////////////////
module main;
import std.stdio;
void reachIf(bool x)()
{
if(!x)
return;
writeln("reached"); // Warning: statement is not reachable
}
void main(string[] args) {
reachIf!true(); // prints "reached"
reachIf!false(); // triggers warning
}
///////////////////////////////
This is, I think, a big problem.
Affected code is rare today, but that is only because DMD's
constant folding and value-range-propagation is weak. The more
improvements are made in this area, the more common erroneous
"statement is not reachable" warnings will become.
Unfortunately, from what I can tell, this bug is just a natural
consequence of DMD's current design; I think an ideal fix will
not be simple.
Some possible solutions:
1. Defer "not reachable" warnings until compilation has been
completed, and only issue the warning if *all* instantiations of
the statement were unreachable.
2. For semantic analysis purposes, first instantiate each
template using dummy parameters with the widest possible VRP
ranges. Only statements found to be "not reachable" in this dummy
run should actually generate warnings.
3. ??? I don't know the compiler internals very well, so I may be
missing a more elegant solution.
From #1 and #2, #2 is the "correct" choice - if implemented
properly, it would produce precisely the results I expect, as a
user.
However, I think it would take a huge patch touching many
different files and functions to implement. This seems excessive,
assuming the only benefit is eliminating some spurious warnings.
#1 would still allow some false positives, but they should be
quite rare, and also solvable by the user. Otherwise, this seems
like a good approach:
* The size and complexity of the patch should be more reasonable.
* If all messages are deferred, it should be easy to condense the
floods of duplicate messages generated by templates. Instead of
getting the same message duplicated once per instantiation, you
could just have one copy with a `x37` next to it or something.
* Likewise, if desired, messages could be sorted by file and line.
The main disadvantage that I see to approach #1 is that messages
will not be printed until compilation is completed - which might
be never, if the compiler hangs or something.
Thoughts?
More information about the Digitalmars-d
mailing list