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