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?

Reply via email to