]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/testsuite/lib/gcov.exp
Update copyright years.
[thirdparty/gcc.git] / gcc / testsuite / lib / gcov.exp
CommitLineData
a5544970 1# Copyright (C) 1997-2019 Free Software Foundation, Inc.
3f93d729
JJ
2
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
cd976c16 5# the Free Software Foundation; either version 3 of the License, or
3f93d729
JJ
6# (at your option) any later version.
7#
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.
12#
13# You should have received a copy of the GNU General Public License
cd976c16
NC
14# along with GCC; see the file COPYING3. If not see
15# <http://www.gnu.org/licenses/>.
3f93d729
JJ
16
17# Verify various kinds of gcov output: line counts, branch percentages,
18# and call return percentages. None of this is language-specific.
19
20global GCOV
21
20d1af89
ML
22#
23# clean-gcov-file -- delete a working file the compiler creates for gcov
24#
25# TESTCASE is the name of the test.
26# SUFFIX is file suffix
27
28proc clean-gcov-file { testcase suffix } {
29 set basename [file tail $testcase]
30 set base [file rootname $basename]
31 remote_file host delete $base.$suffix
32}
33
3f93d729
JJ
34#
35# clean-gcov -- delete the working files the compiler creates for gcov
36#
37# TESTCASE is the name of the test.
38#
39proc clean-gcov { testcase } {
20d1af89
ML
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"
3f93d729
JJ
44}
45
46#
47# verify-lines -- check that line counts are as expected
48#
b616eb02
JJ
49# TESTNAME is the name of the test, including unique flags.
50# TESTCASE is the name of the test file.
3f93d729
JJ
51# FILE is the name of the gcov output file.
52#
b616eb02 53proc verify-lines { testname testcase file } {
3f93d729 54 #send_user "verify-lines\n"
0e485da0 55 global subdir
b616eb02 56
3f93d729 57 set failed 0
d19202ba
NS
58 set fd [open $file r]
59 while { [gets $fd line] >= 0 } {
d407ad67
SP
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.
ddd6f407 62 if [regexp "^ *(\[^:]*): *(\[0-9\\-#]+):.*count\\((\[0-9\\-#=\\.kMGTPEZY\*]+)\\)(.*)" \
0e485da0
NS
63 "$line" all is n shouldbe rest] {
64 if [regexp "^ *{(.*)}" $rest all xfailed] {
65 switch [dg-process-target $xfailed] {
66 "N" { continue }
67 "F" { setup_xfail "*-*-*" }
68 }
69 }
3f93d729 70 if { $is == "" } {
b616eb02 71 fail "$testname line $n: no data available"
3f93d729
JJ
72 incr failed
73 } elseif { $is != $shouldbe } {
b616eb02 74 fail "$testname line $n: is $is:should be $shouldbe"
3f93d729 75 incr failed
0e485da0 76 } else {
b616eb02 77 pass "$testname count for line $n"
3f93d729 78 }
3f93d729
JJ
79 }
80 }
2cc3d93e 81 close $fd
fc8a650e
SS
82 return $failed
83}
84
85
3f93d729
JJ
86#
87# verify-branches -- check that branch percentages are as expected
88#
b616eb02
JJ
89# TESTNAME is the name of the test, including unique flags.
90# TESTCASE is the name of the test file.
3f93d729
JJ
91# FILE is the name of the gcov output file.
92#
93# Checks are based on comments in the source file. This means to look for
94# branch percentages 10 or 90, 20 or 80, and # 70 or 30:
95# /* branch(10, 20, 70) */
96# This means that all specified percentages should have been seen by now:
97# /* branch(end) */
98# All specified percentages must also be seen by the next branch(n) or
99# by the end of the file.
100#
101# Each check depends on the compiler having generated the expected
102# branch instructions. Don't check for branches that might be
103# optimized away or replaced with predicated instructions.
104#
b616eb02 105proc verify-branches { testname testcase file } {
3f93d729 106 #send_user "verify-branches\n"
b616eb02 107
3f93d729 108 set failed 0
3f93d729
JJ
109 set shouldbe ""
110 set fd [open $file r]
111 set n 0
112 while { [gets $fd line] >= 0 } {
d19202ba 113 regexp "^\[^:\]+: *(\[0-9\]+):" "$line" all n
3f93d729
JJ
114 if [regexp "branch" $line] {
115 verbose "Processing branch line $n: $line" 3
116 if [regexp "branch\\((\[0-9 \]+)\\)" "$line" all new_shouldbe] {
117 # All percentages in the current list should have been seen.
118 if {[llength $shouldbe] != 0} {
b616eb02 119 fail "$testname line $n: expected branch percentages not found: $shouldbe"
3f93d729
JJ
120 incr failed
121 set shouldbe ""
122 }
123 set shouldbe $new_shouldbe
124 #send_user "$n: looking for: $shouldbe\n"
125 # Record the percentages to check for. Replace percentage
126 # n > 50 with 100-n, since block ordering affects the
127 # direction of a branch.
128 for {set i 0} {$i < [llength $shouldbe]} {incr i} {
129 set num [lindex $shouldbe $i]
130 if {$num > 50} {
131 set shouldbe [lreplace $shouldbe $i $i [expr 100 - $num]]
132 }
133 }
d19202ba 134 } elseif [regexp "branch +\[0-9\]+ taken (-\[0-9\]+)%" "$line" \
3f93d729
JJ
135 all taken] {
136 # Percentages should never be negative.
b616eb02 137 fail "$testname line $n: negative percentage: $taken"
3f93d729 138 incr failed
d19202ba 139 } elseif [regexp "branch +\[0-9\]+ taken (\[0-9\]+)%" "$line" \
3f93d729
JJ
140 all taken] {
141 #send_user "$n: taken = $taken\n"
142 # Percentages should never be greater than 100.
143 if {$taken > 100} {
b616eb02 144 fail "$testname line $n: branch percentage greater than 100: $taken"
3f93d729
JJ
145 incr failed
146 }
147 if {$taken > 50} {
148 set taken [expr 100 - $taken]
149 }
150 # If this percentage is one to check for then remove it
151 # from the list. It's normal to ignore some reports.
152 set i [lsearch $shouldbe $taken]
153 if {$i != -1} {
154 set shouldbe [lreplace $shouldbe $i $i]
155 }
156 } elseif [regexp "branch\\(end\\)" "$line"] {
157 # All percentages in the list should have been seen by now.
158 if {[llength $shouldbe] != 0} {
b616eb02 159 fail "$testname line n: expected branch percentages not found: $shouldbe"
3f93d729
JJ
160 incr failed
161 }
162 set shouldbe ""
163 }
164 }
165 }
166 # All percentages in the list should have been seen.
167 if {[llength $shouldbe] != 0} {
b616eb02 168 fail "$testname line $n: expected branch percentages not found: $shouldbe"
3f93d729
JJ
169 incr failed
170 }
171 close $fd
d19202ba 172 return $failed
3f93d729
JJ
173}
174
175#
176# verify-calls -- check that call return percentages are as expected
177#
b616eb02
JJ
178# TESTNAME is the name of the test, including unique flags.
179# TESTCASE is the name of the test file.
3f93d729
JJ
180# FILE is the name of the gcov output file.
181#
182# Checks are based on comments in the source file. This means to look for
183# call return percentages 50, 20, 33:
184# /* returns(50, 20, 33) */
185# This means that all specified percentages should have been seen by now:
186# /* returns(end) */
187# All specified percentages must also be seen by the next returns(n) or
188# by the end of the file.
189#
190# Each check depends on the compiler having generated the expected
191# call instructions. Don't check for calls that are inserted by the
192# compiler or that might be inlined.
193#
b616eb02 194proc verify-calls { testname testcase file } {
3f93d729 195 #send_user "verify-calls\n"
b616eb02 196
3f93d729 197 set failed 0
3f93d729
JJ
198 set shouldbe ""
199 set fd [open $file r]
200 set n 0
201 while { [gets $fd line] >= 0 } {
d19202ba 202 regexp "^\[^:\]+: *(\[0-9\]+):" "$line" all n
27283c73 203 if [regexp "return" $line] {
3f93d729
JJ
204 verbose "Processing returns line $n: $line" 3
205 if [regexp "returns\\((\[0-9 \]+)\\)" "$line" all new_shouldbe] {
206 # All percentages in the current list should have been seen.
207 if {[llength $shouldbe] != 0} {
b616eb02 208 fail "$testname line $n: expected return percentages not found: $shouldbe"
3f93d729
JJ
209 incr failed
210 set shouldbe ""
211 }
212 # Record the percentages to check for.
213 set shouldbe $new_shouldbe
27283c73 214 } elseif [regexp "call +\[0-9\]+ returned (-\[0-9\]+)%" "$line" \
3f93d729
JJ
215 all returns] {
216 # Percentages should never be negative.
b616eb02 217 fail "$testname line $n: negative percentage: $returns"
3f93d729 218 incr failed
27283c73 219 } elseif [regexp "call +\[0-9\]+ returned (\[0-9\]+)%" "$line" \
3f93d729
JJ
220 all returns] {
221 # For branches we check that percentages are not greater than
222 # 100 but call return percentages can be, as for setjmp(), so
223 # don't count that as an error.
224 #
225 # If this percentage is one to check for then remove it
226 # from the list. It's normal to ignore some reports.
227 set i [lsearch $shouldbe $returns]
228 if {$i != -1} {
229 set shouldbe [lreplace $shouldbe $i $i]
230 }
231 } elseif [regexp "returns\\(end\\)" "$line"] {
232 # All percentages in the list should have been seen by now.
233 if {[llength $shouldbe] != 0} {
b616eb02 234 fail "$testname line $n: expected return percentages not found: $shouldbe"
3f93d729
JJ
235 incr failed
236 }
237 set shouldbe ""
238 }
239 }
240 }
241 # All percentages in the list should have been seen.
242 if {[llength $shouldbe] != 0} {
b616eb02 243 fail "$testname line $n: expected return percentages not found: $shouldbe"
3f93d729
JJ
244 incr failed
245 }
246 close $fd
d19202ba 247 return $failed
3f93d729
JJ
248}
249
250# Called by dg-final to run gcov and analyze the results.
251#
7ffe3584
MM
252# ARGS consists of the optional strings "branches" and/or "calls",
253# (indicating that these things should be verified) followed by a
254# list of arguments to provide to gcov, including the name of the
255# source file.
3f93d729
JJ
256
257proc run-gcov { args } {
258 global GCOV
259 global srcdir subdir
260
0e485da0 261 set gcov_args ""
7ffe3584
MM
262 set gcov_verify_calls 0
263 set gcov_verify_branches 0
fc8a650e
SS
264 set gcov_verify_lines 1
265 set gcov_verify_intermediate 0
20d1af89 266 set gcov_remove_gcda 0
0e485da0 267 set xfailed 0
3f93d729 268
7ffe3584
MM
269 foreach a $args {
270 if { $a == "calls" } {
271 set gcov_verify_calls 1
272 } elseif { $a == "branches" } {
273 set gcov_verify_branches 1
fc8a650e
SS
274 } elseif { $a == "intermediate" } {
275 set gcov_verify_intermediate 1
276 set gcov_verify_calls 0
277 set gcov_verify_branches 0
278 set gcov_verify_lines 0
20d1af89
ML
279 } elseif { $a == "remove-gcda" } {
280 set gcov_remove_gcda 1
0e485da0
NS
281 } elseif { $gcov_args == "" } {
282 set gcov_args $a
283 } else {
284 switch [dg-process-target $a] {
285 "N" { return }
286 "F" { set xfailed 1 }
287 }
3f93d729
JJ
288 }
289 }
290
e3b205be 291 set testname [testname-for-summary]
b616eb02
JJ
292
293 # Extract the test file name from the arguments.
7ffe3584
MM
294 set testcase [lindex $gcov_args end]
295
20d1af89
ML
296 if { $gcov_remove_gcda } {
297 verbose "Removing $testcase.gcda"
298 clean-gcov-file $testcase "gcda"
299 }
300
3f93d729 301 verbose "Running $GCOV $testcase" 2
11289ef9
BE
302 set testcase [remote_download host $testcase]
303 set result [remote_exec host $GCOV $gcov_args]
3f93d729 304 if { [lindex $result 0] != 0 } {
0e485da0
NS
305 if { $xfailed } {
306 setup_xfail "*-*-*"
307 }
b616eb02 308 fail "$testname gcov failed: [lindex $result 1]"
3f93d729
JJ
309 clean-gcov $testcase
310 return
311 }
312
bebe0086
ML
313 set builtin_index [string first "File '<built-in>'" $result]
314 if { $builtin_index != -1 } {
315 fail "$testname gcov failed: <built-in>.gcov should not be created"
316 clean-gcov $testcase
317 return
318 }
319
3f93d729
JJ
320 # Get the gcov output file after making sure it exists.
321 set files [glob -nocomplain $testcase.gcov]
322 if { $files == "" } {
0e485da0
NS
323 if { $xfailed } {
324 setup_xfail "*-*-*"
325 }
bebe0086 326 fail "$testname gcov failed: $testcase.gcov does not exist"
3f93d729 327 clean-gcov $testcase
11289ef9 328 return
3f93d729 329 }
11289ef9 330 remote_upload host $testcase.gcov $testcase.gcov
3f93d729 331
3f93d729 332 # Check that line execution counts are as expected.
fc8a650e
SS
333 if { $gcov_verify_lines } {
334 # Check that line execution counts are as expected.
335 set lfailed [verify-lines $testname $testcase $testcase.gcov]
336 } else {
337 set lfailed 0
338 }
3f93d729
JJ
339
340 # If requested via the .x file, check that branch and call information
341 # is correct.
7ffe3584 342 if { $gcov_verify_branches } {
b616eb02 343 set bfailed [verify-branches $testname $testcase $testcase.gcov]
3f93d729
JJ
344 } else {
345 set bfailed 0
3f93d729 346 }
7ffe3584 347 if { $gcov_verify_calls } {
b616eb02 348 set cfailed [verify-calls $testname $testcase $testcase.gcov]
3f93d729
JJ
349 } else {
350 set cfailed 0
3f93d729 351 }
fc8a650e
SS
352 if { $gcov_verify_intermediate } {
353 # Check that intermediate format has the expected format
354 set ifailed [verify-intermediate $testname $testcase $testcase.gcov]
355 } else {
356 set ifailed 0
357 }
3f93d729
JJ
358
359 # Report whether the gcov test passed or failed. If there were
360 # multiple failures then the message is a summary.
fc8a650e 361 set tfailed [expr $lfailed + $bfailed + $cfailed + $ifailed]
0e485da0
NS
362 if { $xfailed } {
363 setup_xfail "*-*-*"
364 }
3f93d729 365 if { $tfailed > 0 } {
fc8a650e 366 fail "$testname gcov: $lfailed failures in line counts, $bfailed in branch percentages, $cfailed in return percentages, $ifailed in intermediate format"
70f6380d
TV
367 if { $xfailed } {
368 clean-gcov $testcase
369 }
3f93d729 370 } else {
b616eb02 371 pass "$testname gcov"
3f93d729
JJ
372 clean-gcov $testcase
373 }
374}