August 01, 2015
https://issues.dlang.org/show_bug.cgi?id=14855

          Issue ID: 14855
           Summary: -cov should ignore assert(0)
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: issues.dlang@jmdavisProg.com

This code

void main()
{
}

void foo(int val)
{
    assert(val >= 0 && val <= 5);
    switch(val)
    {
        case 0: /* do something*/ break;
        case 1: /* do something*/ break;
        case 2: /* do something*/ break;
        case 3: /* do something*/ break;
        case 4: /* do something*/ break;
        case 5: /* do something*/ break;
        default: assert(0);
    }
}

unittest
{
    foreach(i; 0 .. 6)
        foo(i);
}

results in this coverage file:

       |void main()
       |{
       |}
       |
       |void foo(int val)
       |{
     12|    assert(val >= 0 && val <= 5);
      6|    switch(val)
       |    {
      2|        case 0: /* do something*/ break;
      2|        case 1: /* do something*/ break;
      2|        case 2: /* do something*/ break;
      2|        case 3: /* do something*/ break;
      2|        case 4: /* do something*/ break;
      2|        case 5: /* do something*/ break;
0000000|        default: assert(0);
       |    }
       |}
       |
       |unittest
       |{
     21|    foreach(i; 0 .. 6)
      6|        foo(i);
       |}
q.d is 90% covered

Clearly, dmd -cov does not consider this to have 100% coverage, because the line with assert(0) never ran. However, the line with assert(0) shouldn't even run. There's a serious bug in the program if it does, and it will kill the program (interestingly enough, that doesn't stop it from generating a coverage report, even with -release, and if the line does run, it'll show that in the coverage report). But it's code that should _not_ be covered and where by definition, there is a problem if it runs.

This is one of the chief issues which prevents programs from being able to reach 100% code coverage even when they're properly tested, and it forces anyone with such code who wants to make sure that they've properly covered their code to manually verify that each uncovered line has an assert(0) on it (or one of the other few cases where a line is uncovered and shouldn't be covered). Whereas if assert(0) were treated as covered (or ignored completely by the coverage analyzer), then such a program would be at 100% code coverage, and no manual verification would be needed. So, the current behavior is a major obstacle in being able to automatically detect 100% code coverage with tools - or even for a programmer to quickly check it themselves. And if we want to be able to have stuff like the auto-tester verify 100% code coverage, then we need to make it so that the cases which should _not_ be covered are not taken into account when calculating the code coverage.

--