1 # Copyright
(C
) 1997-2018 Free Software Foundation
, Inc.
3 # This
program is free software
; you can redistribute it and
/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation
; either version
3 of the License
, or
6 #
(at your option
) any later version.
8 # This
program is distributed in the hope that it will be useful
,
9 # but WITHOUT
ANY WARRANTY
; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License
for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with GCC
; see the file COPYING3.
If not see
15 #
<http
://www.gnu.org
/licenses
/>.
17 # Verify various kinds of gcov output
: line counts
, branch percentages
,
18 # and
call return percentages.
None of this is language
-specific.
23 # clean
-gcov
-file
-- delete a working file the compiler creates
for gcov
25 # TESTCASE is the
name of the test.
26 # SUFFIX is file suffix
28 proc clean
-gcov
-file
{ testcase suffix
} {
29 set basename
[file tail $testcase
]
30 set base
[file rootname $basename
]
31 remote_file host
delete $base.$suffix
35 # clean
-gcov
-- delete the working files the compiler creates
for gcov
37 # TESTCASE is the
name of the test.
39 proc clean
-gcov
{ testcase
} {
40 clean
-gcov
-file $testcase
"gcno"
41 clean
-gcov
-file $testcase
"gcda"
42 clean
-gcov
-file $testcase
"gcov"
43 clean
-gcov
-file $testcase
"h.gcov"
47 # verify
-lines
-- check that line counts are as expected
49 # TESTNAME is the
name of the test
, including unique flags.
50 # TESTCASE is the
name of the test file.
51 # FILE is the
name of the gcov output file.
53 proc verify
-lines
{ testname testcase file
} {
54 #send_user
"verify-lines\n"
59 while { [gets $fd line
] >= 0 } {
60 # We want to match both
"-" and "#####" as count as well as numbers,
61 # since we want to detect lines that shouldn
't be marked as covered.
62 if [regexp "^ *(\[^:]*): *(\[0-9\\-#]+):.*count\\((\[0-9\\-#=\\.kMGTPEZY]+)\\)(.*)" \
63 "$line" all is n shouldbe rest] {
64 if [regexp "^ *{(.*)}" $rest all xfailed] {
65 switch [dg-process-target $xfailed] {
67 "F" { setup_xfail "*-*-*" }
71 fail "$testname line $n: no data available"
73 } elseif { $is != $shouldbe } {
74 fail "$testname line $n: is $is:should be $shouldbe"
77 pass "$testname count for line $n"
87 # verify-intermediate -- check that intermediate file has certain lines
89 # TESTNAME is the name of the test, including unique flags.
90 # TESTCASE is the name of the test.
91 # FILE is the name of the gcov output file.
93 # Checks are very loose, they are based on certain tags being present
94 # in the output. They do not check for exact expected execution
95 # counts. For that the regular gcov format should be checked.
97 proc verify-intermediate { testname testcase file } {
103 set fd [open $file r]
104 while { [gets $fd line] >= 0 } {
105 if [regexp "^file:" $line] {
108 if [regexp "^function:(\[0-9\]+),(\[0-9\]+),.*" $line] {
111 if [regexp "^lcount:(\[0-9\]+),(\[0-9\]+),(\[01\])" $line] {
114 if [regexp "^branch:(\[0-9\]+),(taken|nottaken|notexec)" $line] {
119 # We should see at least one tag of each type
121 fail "$testname expected 'file
:' tag not found"
124 if {$function == 0} {
125 fail "$testname expected 'function
:' tag not found"
129 fail "$testname expected 'lcount
:' tag not found"
133 fail "$testname expected 'branch
:' tag not found"
141 # verify-branches -- check that branch percentages are as expected
143 # TESTNAME is the name of the test, including unique flags.
144 # TESTCASE is the name of the test file.
145 # FILE is the name of the gcov output file.
147 # Checks are based on comments in the source file. This means to look for
148 # branch percentages 10 or 90, 20 or 80, and # 70 or 30:
149 # /* branch(10, 20, 70) */
150 # This means that all specified percentages should have been seen by now:
152 # All specified percentages must also be seen by the next branch(n) or
153 # by the end of the file.
155 # Each check depends on the compiler having generated the expected
156 # branch instructions. Don't check
for branches that might be
157 # optimized away or replaced with predicated instructions.
159 proc verify
-branches
{ testname testcase file
} {
160 #send_user
"verify-branches\n"
164 set fd
[open $file r
]
166 while { [gets $fd line
] >= 0 } {
167 regexp
"^\[^:\]+: *(\[0-9\]+):" "$line" all n
168 if [regexp
"branch" $line] {
169 verbose
"Processing branch line $n: $line" 3
170 if [regexp
"branch\\((\[0-9 \]+)\\)" "$line" all new_shouldbe] {
171 # All percentages in the current list should have been seen.
172 if {[llength $shouldbe
] != 0} {
173 fail
"$testname line $n: expected branch percentages not found: $shouldbe"
177 set shouldbe $new_shouldbe
178 #send_user
"$n: looking for: $shouldbe\n"
179 # Record the percentages to check
for. Replace
percentage
180 # n
> 50 with
100-n
, since block ordering affects the
181 # direction of a branch.
182 for {set i
0} {$i
< [llength $shouldbe
]} {incr i
} {
183 set num
[lindex $shouldbe $i
]
185 set shouldbe
[lreplace $shouldbe $i $i
[expr
100 - $num
]]
188 } elseif
[regexp
"branch +\[0-9\]+ taken (-\[0-9\]+)%" "$line" \
190 # Percentages should never be negative.
191 fail
"$testname line $n: negative percentage: $taken"
193 } elseif
[regexp
"branch +\[0-9\]+ taken (\[0-9\]+)%" "$line" \
195 #send_user
"$n: taken = $taken\n"
196 # Percentages should never be greater than
100.
198 fail
"$testname line $n: branch percentage greater than 100: $taken"
202 set taken
[expr
100 - $taken
]
204 #
If this
percentage is one to check
for then remove it
205 # from the list. It
's normal to ignore some reports.
206 set i [lsearch $shouldbe $taken]
208 set shouldbe [lreplace $shouldbe $i $i]
210 } elseif [regexp "branch\\(end\\)" "$line"] {
211 # All percentages in the list should have been seen by now.
212 if {[llength $shouldbe] != 0} {
213 fail "$testname line n: expected branch percentages not found: $shouldbe"
220 # All percentages in the list should have been seen.
221 if {[llength $shouldbe] != 0} {
222 fail "$testname line $n: expected branch percentages not found: $shouldbe"
230 # verify-calls -- check that call return percentages are as expected
232 # TESTNAME is the name of the test, including unique flags.
233 # TESTCASE is the name of the test file.
234 # FILE is the name of the gcov output file.
236 # Checks are based on comments in the source file. This means to look for
237 # call return percentages 50, 20, 33:
238 # /* returns(50, 20, 33) */
239 # This means that all specified percentages should have been seen by now:
241 # All specified percentages must also be seen by the next returns(n) or
242 # by the end of the file.
244 # Each check depends on the compiler having generated the expected
245 # call instructions. Don't check
for calls that are inserted by the
246 # compiler or that might be inlined.
248 proc verify
-calls
{ testname testcase file
} {
249 #send_user
"verify-calls\n"
253 set fd
[open $file r
]
255 while { [gets $fd line
] >= 0 } {
256 regexp
"^\[^:\]+: *(\[0-9\]+):" "$line" all n
257 if [regexp
"return" $line] {
258 verbose
"Processing returns line $n: $line" 3
259 if [regexp
"returns\\((\[0-9 \]+)\\)" "$line" all new_shouldbe] {
260 # All percentages in the current list should have been seen.
261 if {[llength $shouldbe
] != 0} {
262 fail
"$testname line $n: expected return percentages not found: $shouldbe"
266 # Record the percentages to check
for.
267 set shouldbe $new_shouldbe
268 } elseif
[regexp
"call +\[0-9\]+ returned (-\[0-9\]+)%" "$line" \
270 # Percentages should never be negative.
271 fail
"$testname line $n: negative percentage: $returns"
273 } elseif
[regexp
"call +\[0-9\]+ returned (\[0-9\]+)%" "$line" \
275 #
For branches we check that percentages are not greater than
276 #
100 but
call return percentages can be
, as
for setjmp
(), so
277 # don
't count that as an error.
279 # If this percentage is one to check for then remove it
280 # from the list. It's
normal to ignore some reports.
281 set i
[lsearch $shouldbe $returns
]
283 set shouldbe
[lreplace $shouldbe $i $i
]
285 } elseif
[regexp
"returns\\(end\\)" "$line"] {
286 # All percentages in the list should have been seen by now.
287 if {[llength $shouldbe
] != 0} {
288 fail
"$testname line $n: expected return percentages not found: $shouldbe"
295 # All percentages in the list should have been seen.
296 if {[llength $shouldbe
] != 0} {
297 fail
"$testname line $n: expected return percentages not found: $shouldbe"
304 # Called by dg
-final to run gcov and analyze the results.
306 #
ARGS consists of the optional strings
"branches" and/or "calls",
307 #
(indicating that these things should be verified
) followed by a
308 # list of arguments to provide to gcov
, including the
name of the
311 proc run
-gcov
{ args } {
316 set gcov_verify_calls
0
317 set gcov_verify_branches
0
318 set gcov_verify_lines
1
319 set gcov_verify_intermediate
0
320 set gcov_remove_gcda
0
324 if { $a
== "calls" } {
325 set gcov_verify_calls
1
326 } elseif
{ $a
== "branches" } {
327 set gcov_verify_branches
1
328 } elseif
{ $a
== "intermediate" } {
329 set gcov_verify_intermediate
1
330 set gcov_verify_calls
0
331 set gcov_verify_branches
0
332 set gcov_verify_lines
0
333 } elseif
{ $a
== "remove-gcda" } {
334 set gcov_remove_gcda
1
335 } elseif
{ $gcov_args
== "" } {
338 switch [dg
-process
-target $a
] {
340 "F" { set xfailed 1 }
345 set testname
[testname
-for-summary
]
347 # Extract the test file
name from the arguments.
348 set testcase
[lindex $gcov_args end
]
350 if { $gcov_remove_gcda
} {
351 verbose
"Removing $testcase.gcda"
352 clean
-gcov
-file $testcase
"gcda"
355 verbose
"Running $GCOV $testcase" 2
356 set testcase
[remote_download host $testcase
]
357 set result
[remote_exec host $GCOV $gcov_args
]
358 if { [lindex $result
0] != 0 } {
362 fail
"$testname gcov failed: [lindex $result 1]"
367 set builtin_index
[string first
"File '<built-in>'" $result]
368 if { $builtin_index
!= -1 } {
369 fail
"$testname gcov failed: <built-in>.gcov should not be created"
374 #
Get the gcov output file after making sure it
exists.
375 set files
[glob
-nocomplain $testcase.gcov
]
376 if { $files
== "" } {
380 fail
"$testname gcov failed: $testcase.gcov does not exist"
384 remote_upload host $testcase.gcov $testcase.gcov
386 # Check that line execution counts are as expected.
387 if { $gcov_verify_lines
} {
388 # Check that line execution counts are as expected.
389 set lfailed
[verify
-lines $testname $testcase $testcase.gcov
]
394 #
If requested via the .x file
, check that branch and
call information
396 if { $gcov_verify_branches
} {
397 set bfailed
[verify
-branches $testname $testcase $testcase.gcov
]
401 if { $gcov_verify_calls
} {
402 set cfailed
[verify
-calls $testname $testcase $testcase.gcov
]
406 if { $gcov_verify_intermediate
} {
407 # Check that intermediate format has the expected format
408 set ifailed
[verify
-intermediate $testname $testcase $testcase.gcov
]
413 #
Report whether the gcov test passed or failed.
If there were
414 # multiple failures
then the message is a summary.
415 set tfailed
[expr $lfailed
+ $bfailed
+ $cfailed
+ $ifailed
]
419 if { $tfailed
> 0 } {
420 fail
"$testname gcov: $lfailed failures in line counts, $bfailed in branch percentages, $cfailed in return percentages, $ifailed in intermediate format"
425 pass
"$testname gcov"