1# Tests for compatibility between llvm-cov and gcov. These work by
2# comparing llvm-cov against reference outputs generated by gcov 4.2.
3
4# Test fails on Windows where internal shell is used due to path separator
5# mismatches.
6REQUIRES: shell
7
8RUN: rm -rf %t
9RUN: mkdir %t
10RUN: cd %t
11RUN: cp %p/Inputs/test* .
12
13# Basic behaviour with no flags
14RUN: llvm-cov gcov test.c 2> %t.err | FileCheck %s --check-prefixes=OUT,OUTFILE --match-full-lines --strict-whitespace
15RUN: FileCheck %s --check-prefix=C --match-full-lines --strict-whitespace < test.cpp.gcov
16RUN: diff -ub test_no_options.h.gcov test.h.gcov
17RUN: count 0 < %t.err
18
19# Same, but specifying the object directory
20RUN: mkdir -p %t/objdir
21RUN: cp test.gcno test.gcda %t/objdir
22RUN: llvm-cov gcov -o objdir test.c | FileCheck %s --check-prefixes=OUT,OUTFILE
23RUN: FileCheck --input-file=test.cpp.gcov %s --check-prefix=OBJDIR
24OBJDIR:      0:Graph:objdir/test.gcno
25OBJDIR-NEXT: 0:Data:objdir/test.gcda
26
27# Specifying an object file
28RUN: llvm-cov gcov -o objdir/test.o test.c
29RUN: FileCheck --input-file=test.cpp.gcov %s --check-prefix=OBJDIR
30
31# Specifying an object file that could be ambiguous with a directory
32RUN: llvm-cov gcov -o objdir/test test.c
33RUN: FileCheck --input-file=test.cpp.gcov %s --check-prefix=OBJDIR
34
35# With gcov output disabled
36RUN: llvm-cov gcov -n test.c | FileCheck %s --check-prefix=OUT
37
38# Print to stdout.
39RUN: llvm-cov gcov -t test.c > stdout
40RUN: llvm-cov gcov --stdout test.c | cmp stdout -
41RUN: cat test_no_options.cpp.gcov test_no_options.h.gcov | diff -u - stdout
42RUN: llvm-cov gcov -n -t test.c | count 0
43
44RUN: llvm-cov gcov test_paths.cpp 2>/dev/null | FileCheck %s --check-prefix=MISSING
45RUN: ls a.c.gcov
46MISSING: File 'src/./n/../a.c'
47MISSING: Creating 'a.c.gcov'
48
49# Preserve paths. This mangles the output filenames.
50RUN: llvm-cov gcov -p test_paths.cpp 2>/dev/null | FileCheck %s --check-prefix=PRESERVE
51RUN: ls src#n#^#a.c.gcov
52PRESERVE: File 'src/./n/../a.c'
53PRESERVE: Creating 'src#n#^#a.c.gcov'
54
55# Long file names.
56RUN: llvm-cov gcov -l test_paths.cpp
57RUN: ls test_paths.cpp##a.c.gcov
58
59# Long file names and preserve paths.
60RUN: mkdir -p src && llvm-cov gcov -lp -gcno test_paths.gcno -gcda test_paths.gcda src/../test_paths.cpp
61RUN: ls src#^#test_paths.cpp##src#n#^#a.c.gcov
62
63# Hash pathnames.
64RUN: llvm-cov gcov -x -gcno test_paths.gcno -gcda test_paths.gcda src/../test_paths.cpp
65RUN: ls a.c##4784150e272908907eaa7380ca3eced8.gcov
66
67# Function summaries. This changes stdout, but not the gcov files.
68RUN: llvm-cov gcov test.c -f | FileCheck %s --check-prefixes=OUT,OUTFILE,OUT-F
69RUN: FileCheck --input-file=test.cpp.gcov %s --check-prefix=C
70RUN: FileCheck --input-file=test.h.gcov %s --check-prefix=H
71
72# All blocks. This doesn't affect stdout, only the gcov files.
73RUN: llvm-cov gcov test.c -a | FileCheck %s --check-prefixes=OUT,OUTFILE
74RUN: FileCheck --input-file=test.cpp.gcov %s --check-prefixes=C,C-A
75RUN: FileCheck --input-file=test.h.gcov %s --check-prefixes=H,H-A
76
77# Branch probabilities.
78RUN: llvm-cov gcov test.c -a -b | FileCheck %s --check-prefixes=OUT,OUTFILE,OUT-B
79RUN: FileCheck --input-file=test.cpp.gcov %s --check-prefixes=C,C-A,C-B
80RUN: FileCheck --input-file=test.h.gcov %s --check-prefixes=H,H-A,H-B
81
82# Function summaries including branch probabilities.
83RUN: llvm-cov gcov test.c -a -b -f | FileCheck %s --check-prefixes=OUT,OUTFILE,OUT-F,OUT-B,OUT-FB --match-full-lines --strict-whitespace
84RUN: FileCheck %s --check-prefixes=C,C-A,C-B --match-full-lines --strict-whitespace < test.cpp.gcov
85RUN: FileCheck %s --check-prefixes=H,H-A,H-B --match-full-lines --strict-whitespace < test.h.gcov
86
87       OUT-F:Function '_ZN1A1BEv'
88  OUT-F-NEXT:Lines executed:100.00% of 1
89 OUT-FB-NEXT:No branches
90 OUT-FB-NEXT:No calls
91 OUT-F-EMPTY:
92  OUT-F-NEXT:Function '_Z7uselessv'
93  OUT-F-NEXT:Lines executed:0.00% of 1
94 OUT-FB-NEXT:No branches
95 OUT-FB-NEXT:No calls
96 OUT-F-EMPTY:
97  OUT-F-NEXT:Function '_Z12more_uselessv'
98  OUT-F-NEXT:Lines executed:0.00% of 2
99 OUT-FB-NEXT:No branches
100 OUT-FB-NEXT:No calls
101 OUT-F-EMPTY:
102  OUT-F-NEXT:Function '_Z3foov'
103  OUT-F-NEXT:Lines executed:100.00% of 3
104 OUT-FB-NEXT:No branches
105 OUT-FB-NEXT:No calls
106 OUT-F-EMPTY:
107  OUT-F-NEXT:Function '_Z3barv'
108  OUT-F-NEXT:Lines executed:0.00% of 3
109 OUT-FB-NEXT:No branches
110 OUT-FB-NEXT:No calls
111 OUT-F-EMPTY:
112  OUT-F-NEXT:Function '_Z6assignii'
113  OUT-F-NEXT:Lines executed:100.00% of 3
114 OUT-FB-NEXT:No branches
115 OUT-FB-NEXT:No calls
116 OUT-F-EMPTY:
117  OUT-F-NEXT:Function '_Z15initialize_gridv'
118  OUT-F-NEXT:Lines executed:100.00% of 5
119 OUT-FB-NEXT:No branches
120 OUT-FB-NEXT:No calls
121 OUT-F-EMPTY:
122  OUT-F-NEXT:Function 'main'
123  OUT-F-NEXT:Lines executed:92.00% of 25
124 OUT-FB-NEXT:No branches
125 OUT-FB-NEXT:No calls
126 OUT-F-EMPTY:
127  OUT-F-NEXT:Function '_ZN1AC2Ev'
128  OUT-F-NEXT:Lines executed:100.00% of 1
129 OUT-FB-NEXT:No branches
130 OUT-FB-NEXT:No calls
131 OUT-F-EMPTY:
132         OUT:File 'test.cpp'
133    OUT-NEXT:Lines executed:81.40% of 43
134  OUT-B-NEXT:Branches executed:100.00% of 15
135  OUT-B-NEXT:Taken at least once:86.67% of 15
136  OUT-B-NEXT:No calls
137OUTFILE-NEXT:Creating 'test.cpp.gcov'
138   OUT-EMPTY:
139    OUT-NEXT:File './test.h'
140    OUT-NEXT:Lines executed:100.00% of 1
141  OUT-B-NEXT:No branches
142  OUT-B-NEXT:No calls
143OUTFILE-NEXT:Creating 'test.h.gcov'
144
145# Summarize unconditional branches too.
146RUN: llvm-cov gcov test.c -a -b -u | FileCheck %s --check-prefixes=OUT,OUTFILE,OUT-B
147RUN: FileCheck --input-file=test.cpp.gcov %s --check-prefixes=C,C-A,C-B,C-U
148RUN: FileCheck --input-file=test.h.gcov %s --check-prefixes=H,H-A,H-B,H-U
149
150# Absolute counts for branches.
151RUN: llvm-cov gcov test.c -a -b -c -u
152RUN: FileCheck --input-file=test.h.gcov %s --check-prefix=H-C
153H-C: unconditional  0 taken 1
154
155# Missing gcda file just gives 0 counts.
156RUN: llvm-cov gcov test.c -gcda=no_such_gcda_file | FileCheck %s --check-prefix=NO-GCDA
157RUN: diff -ub test_no_gcda.cpp.gcov test.cpp.gcov
158RUN: diff -ub test_no_gcda.h.gcov test.h.gcov
159NO-GCDA:       File 'test.cpp'
160NO-GCDA-NEXT:  Lines executed:0.00% of 43
161NO-GCDA-NEXT:  Creating 'test.cpp.gcov'
162NO-GCDA-EMPTY:
163NO-GCDA-NEXT:  File './test.h'
164NO-GCDA-NEXT:  Lines executed:0.00% of 1
165NO-GCDA-NEXT:  Creating 'test.h.gcov'
166
167# Invalid gcno file.
168RUN: llvm-cov gcov test.c -gcno=test_read_fail.gcno
169
170# Not a .gcda file. Error but keep the .gcov output.
171RUN: echo invalid > not.gcda
172RUN: llvm-cov gcov test.c -gcda=not.gcda 2> %t.err | FileCheck %s --check-prefix=NO-GCDA
173RUN: FileCheck %s --check-prefix=NOT-GCDA < %t.err
174NOT-GCDA: not.gcda:not a gcov data file
175
176# Bad file checksum on gcda.
177RUN: llvm-cov gcov test.c -gcda=test_file_checksum_fail.gcda 2> %t.err | FileCheck %s --check-prefix=NO-GCDA
178
179# Bad function checksum on gcda
180RUN: llvm-cov gcov test.c -gcda=test_func_checksum_fail.gcda 2> %t.err | FileCheck %s --check-prefix=NO-GCDA
181
182# Has arcs from exit blocks
183RUN-DISABLED: llvm-cov gcov test_exit_block_arcs.c 2>&1 | FileCheck %s -check-prefix=EXIT_BLOCK_ARCS
184EXIT_BLOCK_ARCS: (main) has arcs from exit block.
185
186
187     C:        -:    0:Source:test.cpp
188C-NEXT:        -:    0:Graph:test.gcno
189C-NEXT:        -:    0:Data:test.gcda
190C-NEXT:        -:    0:Runs:1
191C-NEXT:        -:    0:Programs:1
192C-NEXT:        -:    1:#include "test.h"
193C-NEXT:        -:    2:#include <cstdlib>
194C-NEXT:        -:    3:
195C-NEXT:        -:    4:bool on = false;
196C-NEXT:        -:    5:int len = 42;
197C-NEXT:        -:    6:double grid[10][10] = {0};
198C-NEXT:        -:    7:const char * hello = "world";
199C-NEXT:        -:    8:const char * world = "hello";
200C-NEXT:        -:    9:
201   C-B:function _ZN1A1BEv called 4294967296 returned 100% blocks executed 100%
202C-NEXT:4294967296:   10:void A::B() {}
203   C-A:4294967296:   10-block  0
204   C-U:unconditional  0 taken 100%
205   C-A:4294967296:   10-block  1
206   C-U:unconditional  1 taken 100%
207C-NEXT:        -:   11:
208   C-B:function _Z7uselessv called 0 returned 0% blocks executed 0%
209C-NEXT:    #####:   12:void useless() {}
210   C-A:    $$$$$:   12-block  0
211   C-U:unconditional  0 never executed
212   C-A:    $$$$$:   12-block  1
213   C-U:unconditional  1 never executed
214C-NEXT:        -:   13:
215   C-B:function _Z12more_uselessv called 0 returned 0% blocks executed 0%
216C-NEXT:    #####:   14:double more_useless() {
217C-NEXT:    #####:   15:  return 0;
218   C-A:    $$$$$:   15-block  0
219   C-U:unconditional  0 never executed
220   C-A:    $$$$$:   15-block  1
221   C-U:unconditional  1 never executed
222C-NEXT:        -:   16:}
223C-NEXT:        -:   17:
224   C-B:function _Z3foov called 1 returned 100% blocks executed 100%
225C-NEXT:        1:   18:int foo() {
226C-NEXT:        1:   19:  on = true;
227   C-A:        1:   19-block  0
228   C-U:unconditional  0 taken 100%
229C-NEXT:        1:   20:  return 3;
230   C-A:        1:   20-block  0
231   C-U:unconditional  0 taken 100%
232C-NEXT:        -:   21:}
233C-NEXT:        -:   22:
234   C-B:function _Z3barv called 0 returned 0% blocks executed 0%
235C-NEXT:    #####:   23:int bar() {
236C-NEXT:    #####:   24:  len--;
237   C-A:    $$$$$:   24-block  0
238   C-U:unconditional  0 never executed
239C-NEXT:    #####:   25:  return foo() + 45;
240   C-A:    $$$$$:   25-block  0
241   C-U:unconditional  0 never executed
242C-NEXT:        -:   26:}
243C-NEXT:        -:   27:
244   C-B:function _Z6assignii called 4 returned 100% blocks executed 100%
245C-NEXT:        4:   28:void assign(int ii, int jj) {
246   C-A:        4:   28-block  0
247   C-U:unconditional  0 taken 100%
248C-NEXT:        4:   29:  grid[ii][jj] = (ii+1) * (jj+1);
249C-NEXT:        4:   30:}
250   C-A:        4:   30-block  0
251   C-U:unconditional  0 taken 100%
252C-NEXT:        -:   31:
253   C-B:function _Z15initialize_gridv called 1 returned 100% blocks executed 100%
254C-NEXT:        1:   32:void initialize_grid() {
255C-NEXT:        3:   33:  for (int ii = 0; ii < 2; ii++)
256   C-A:        1:   33-block  0
257   C-U:unconditional  0 taken 100%
258   C-A:        1:   33-block  1
259   C-U:unconditional  1 taken 100%
260   C-A:        3:   33-block  2
261   C-B:branch  {{[02]}} taken 67%
262   C-B:branch  {{[13]}} taken 33%
263   C-A:        2:   33-block  3
264   C-U:unconditional  4 taken 100%
265C-NEXT:        6:   34:    for (int jj = 0; jj < 2; jj++)
266   C-A:        2:   34-block  0
267   C-U:unconditional  0 taken 100%
268   C-A:        6:   34-block  1
269   C-B:branch  {{[01]}} taken 67%
270   C-B:branch  {{[12]}} taken 33%
271   C-A:        4:   34-block  2
272   C-U:unconditional  3 taken 100%
273C-NEXT:        6:   35:      assign(ii, jj);
274   C-A:        4:   35-block  0
275   C-U:unconditional  0 taken 100%
276   C-A:        2:   35-block  1
277   C-U:unconditional  1 taken 100%
278C-NEXT:        1:   36:}
279   C-A:        1:   36-block  0
280   C-U:unconditional  0 taken 100%
281C-NEXT:        -:   37:
282   C-B:function main called 1 returned 100% blocks executed 94%
283C-NEXT:        1:   38:int main() {
284   C-A:        1:   38-block  0
285   C-U:unconditional  0 taken 100%
286C-NEXT:        1:   39:  initialize_grid();
287C-NEXT:        -:   40:
288C-NEXT:        1:   41:  int a = 2;
289C-NEXT:        1:   42:  on = rand() % 2;
290C-NEXT:        1:   43:  if (on) {
291   C-A:        1:   43-block  0
292   C-B:branch  0 taken 100%
293   C-B:branch  1 taken 0%
294C-NEXT:        1:   44:    foo();
295C-NEXT:        1:   45:    ++a;
296C-NEXT:        1:   46:  } else {
297   C-A:        1:   46-block  0
298   C-U:unconditional  0 taken 100%
299C-NEXT:    #####:   47:    bar();
300C-NEXT:    #####:   48:    a += rand();
301   C-A:    $$$$$:   48-block  0
302   C-U:unconditional  0 never executed
303C-NEXT:        -:   49:  }
304C-NEXT:        -:   50:
305C-NEXT:       11:   51:  for (int ii = 0; ii < 10; ++ii) {
306   C-A:        1:   51-block  0
307   C-U:unconditional  0 taken 100%
308   C-A:       11:   51-block  1
309   C-B:branch  {{[01]}} taken 91%
310   C-B:branch  {{[12]}} taken 9%
311   C-A:       10:   51-block  2
312   C-U:unconditional  3 taken 100%
313C-NEXT:       10:   52:    switch (rand() % 5) {
314   C-A:       10:   52-block  0
315   C-B:branch  0 taken 10%
316   C-B:branch  1 taken 20%
317   C-B:branch  2 taken 0%
318   C-B:branch  3 taken 40%
319   C-B:branch  4 taken 30%
320C-NEXT:        -:   53:      case 0:
321C-NEXT:        2:   54:        a += rand();
322C-NEXT:        2:   55:        break;
323   C-A:        2:   55-block  0
324   C-U:unconditional  0 taken 100%
325C-NEXT:        -:   56:      case 1:
326C-NEXT:        -:   57:      case 2:
327C-NEXT:        4:   58:        a += rand() / rand();
328C-NEXT:        4:   59:        break;
329   C-A:        4:   59-block  0
330   C-U:unconditional  0 taken 100%
331C-NEXT:        -:   60:      case 3:
332C-NEXT:        3:   61:        a -= rand();
333C-NEXT:        3:   62:        break;
334   C-A:        3:   62-block  0
335   C-U:unconditional  0 taken 100%
336C-NEXT:        -:   63:      default:
337C-NEXT:        1:   64:        a = -1;
338C-NEXT:        1:   65:    }
339   C-A:        1:   65-block  0
340   C-U:unconditional  0 taken 100%
341C-NEXT:       10:   66:  }
342   C-A:       10:   66-block  0
343   C-U:unconditional  0 taken 100%
344C-NEXT:        -:   67:
345C-NEXT:        1:   68:  A thing;
346C-NEXT:4294967297:   69:  for (uint64_t ii = 0; ii < 4294967296; ++ii)
347   C-A:        1:   69-block  0
348   C-U:unconditional  0 taken 100%
349   C-A:4294967297:   69-block  1
350   C-B:branch  {{[01]}} taken 99%
351   C-B:branch  {{[12]}} taken 1%
352   C-A:4294967296:   69-block  2
353   C-U:unconditional  3 taken 100%
354C-NEXT:4294967296:   70:    thing.B();
355   C-A:4294967296:   70-block  0
356   C-U:unconditional  0 taken 100%
357C-NEXT:        -:   71:
358C-NEXT:        1:   72:  return a + 8 + grid[2][3] + len;
359   C-A:        1:   72-block  0
360   C-U:unconditional  0 taken 100%
361C-NEXT:        -:   73:  return more_useless();
362C-NEXT:        -:   74:}
363
364     H:        -:    0:Source:./test.h
365H-NEXT:        -:    0:Graph:test.gcno
366H-NEXT:        -:    0:Data:test.gcda
367H-NEXT:        -:    0:Runs:1
368H-NEXT:        -:    0:Programs:1
369H-NEXT:        -:    1:#include <stdint.h>
370   H-B:function _ZN1AC2Ev called 1 returned 100% blocks executed 100%
371H-NEXT:        1:    2:struct A {
372   H-A:        1:    2-block  0
373   H-U:unconditional  0 taken 100%
374H-NEXT:        -:    3:  virtual void B();
375H-NEXT:        -:    4:};
376