www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 21032] New: Code coverage (-cov) with templates with nested

https://issues.dlang.org/show_bug.cgi?id=21032

          Issue ID: 21032
           Summary: Code coverage (-cov) with templates with nested
                    functions of different types
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: john.michael.hall gmail.com

-cov will not report missing coverage in the case of templates with nested
functions whose top-level type is not used as part of any lower level function
templates. 

Compiling below with `dmd -unittest -cov covtest.d` and running to get the
associated coverage file (below that) shows 100% even though the function foo
with one parameter is not called.

The function foo with two parameters is correctly marked as being called. While
the version of foo with one parameter is not marked, it also the 0000000 you
would see in the case of bar or baz below if their one parameter versions were
not included.

This is somewhat related to issue 9721
(https://issues.dlang.org/show_bug.cgi?id=9721), but that issue is about more
general templates and this is only concerning templates with nested functions.
In particular, it seems the issue appears when the type of the top-level
template does not match one of the template parameters in the lower-levels.


covtest.d
```
module covtest;

enum Test {
    test1,
    test2
}

template foo(Test test) {
    T foo(T)(T x, T y) {
        return x + y;
    }

    T foo(T)(T x) {
        return x;
    }
}

unittest {
    assert(foo!(Test.test1)(1, 2) == 3);
}

template bar(T) {
    T bar(U)(T x, U y) {
        return x + cast(T) y;
    }

    T bar(T x) {
        return x;
    }
}

unittest {
    assert(bar!int(1, 2f) == 3);
    assert(bar!int(1) == 1);
}

int baz(int x, int y) {
    return x + y;
}

int baz(int x) {
    return x;
}

unittest {
    assert(baz(1, 2) == 3);
    assert(baz(1) == 1);
}

void main() {

}
```

covtest.lst
```
       |module covtest;
       |
       |enum Test {
       |    test1,
       |    test2
       |}
       |
       |template foo(Test test) {
       |    T foo(T)(T x, T y) {
      1|        return x + y;
       |    }
       |    
       |    T foo(T)(T x) {
       |        return x;
       |    }
       |}
       |
       |unittest {
      1|    assert(foo!(Test.test1)(1, 2) == 3);
       |}
       |
       |template bar(T) {
       |    T bar(U)(T x, U y) {
      1|        return x + cast(T) y;
       |    }
       |    
       |    T bar(T x) {
      1|        return x;
       |    }
       |}
       |
       |unittest {
      1|    assert(bar!int(1, 2f) == 3);
      1|    assert(bar!int(1) == 1);
       |}
       |
       |int baz(int x, int y) {
      1|    return x + y;
       |}
       |
       |int baz(int x) {
      1|    return x;
       |}
       |
       |unittest {
      1|    assert(baz(1, 2) == 3);
      1|    assert(baz(1) == 1);
       |}
       |
       |void main() {
       |
       |}
covtest.d is 100% covered

```

--
Jul 10 2020