OSDN Git Service

include/
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / lib / gcc-dg.exp
1 #   Copyright (C) 1997, 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
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
5 # the Free Software Foundation; either version 2 of the License, or
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
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16
17 load_lib dg.exp
18 load_lib file-format.exp
19 load_lib target-supports.exp
20 load_lib target-supports-dg.exp
21 load_lib scanasm.exp
22 load_lib scantree.exp
23 load_lib prune.exp
24 load_lib libgloss.exp
25 load_lib target-libpath.exp
26
27 # We set LC_ALL and LANG to C so that we get the same error messages as expected.
28 setenv LC_ALL C
29 setenv LANG C
30
31 if ![info exists TORTURE_OPTIONS] {
32     # It is theoretically beneficial to group all of the O2/O3 options together,
33     # as in many cases the compiler will generate identical executables for
34     # all of them--and the c-torture testsuite will skip testing identical
35     # executables multiple times.
36     # Also note that -finline-functions is explicitly included in one of the
37     # items below, even though -O3 is also specified, because some ports may
38     # choose to disable inlining functions by default, even when optimizing.
39     set TORTURE_OPTIONS [list \
40         { -O0 } \
41         { -O1 } \
42         { -O2 } \
43         { -O3 -fomit-frame-pointer } \
44         { -O3 -fomit-frame-pointer -funroll-loops } \
45         { -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions } \
46         { -O3 -g } \
47         { -Os } ]
48 }
49
50 global GCC_UNDER_TEST
51 if ![info exists GCC_UNDER_TEST] {
52     set GCC_UNDER_TEST "[find_gcc]"
53 }
54
55 global orig_environment_saved
56
57 # This file may be sourced, so don't override environment settings
58 # that have been previously setup.
59 if { $orig_environment_saved == 0 } {
60     append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
61     set_ld_library_path_env_vars
62 }
63
64 # Split TORTURE_OPTIONS into two choices: one for testcases with loops and
65 # one for testcases without loops.
66
67 set torture_with_loops $TORTURE_OPTIONS
68 set torture_without_loops ""
69 foreach option $TORTURE_OPTIONS {
70     if ![string match "*loop*" $option] {
71         lappend torture_without_loops $option
72     }
73 }
74
75 # Define gcc callbacks for dg.exp.
76
77 proc gcc-dg-test-1 { target_compile prog do_what extra_tool_flags } {
78     # Set up the compiler flags, based on what we're going to do.
79
80     set options [list]
81
82     # Tests should be able to use "dg-do repo".  However, the dg test
83     # driver checks the argument to dg-do against a list of acceptable
84     # options, and "repo" is not among them.  Therefore, we resort to
85     # this ugly approach.
86     if [string match "*-frepo*" $extra_tool_flags] then {
87         set do_what "repo"
88     }
89
90     switch $do_what {
91         "preprocess" {
92             set compile_type "preprocess"
93             set output_file "[file rootname [file tail $prog]].i"
94         }
95         "compile" {
96             set compile_type "assembly"
97             set output_file "[file rootname [file tail $prog]].s"
98         }
99         "assemble" {
100             set compile_type "object"
101             set output_file "[file rootname [file tail $prog]].o"
102         }
103         "precompile" {
104             set compile_type "precompiled_header"
105             set output_file "[file tail $prog].gch"
106         }
107         "link" {
108             set compile_type "executable"
109             set output_file "[file rootname [file tail $prog]].exe"
110             # The following line is needed for targets like the i960 where
111             # the default output file is b.out.  Sigh.
112         }
113         "repo" {
114             set compile_type "object"
115             set output_file "[file rootname [file tail $prog]].o"
116         }
117         "run" {
118             set compile_type "executable"
119             # FIXME: "./" is to cope with "." not being in $PATH.
120             # Should this be handled elsewhere?
121             # YES.
122             set output_file "./[file rootname [file tail $prog]].exe"
123             # This is the only place where we care if an executable was
124             # created or not.  If it was, dg.exp will try to run it.
125             remote_file build delete $output_file
126         }
127         default {
128             perror "$do_what: not a valid dg-do keyword"
129             return ""
130         }
131     }
132
133     if { $extra_tool_flags != "" } {
134         lappend options "additional_flags=$extra_tool_flags"
135     }
136
137     set comp_output [$target_compile "$prog" "$output_file" "$compile_type" $options]
138
139     if { $do_what == "repo" } {
140         set object_file "$output_file"
141         set output_file "[file rootname [file tail $prog]].exe"
142         set comp_output \
143             [ concat $comp_output \
144                   [$target_compile "$object_file" "$output_file" \
145                        "executable" $options] ]
146     }
147
148     return [list $comp_output $output_file]
149 }
150
151 proc gcc-dg-test { prog do_what extra_tool_flags } {
152     return [gcc-dg-test-1 gcc_target_compile $prog $do_what $extra_tool_flags]
153 }
154
155 proc gcc-dg-prune { system text } {
156     global additional_prunes
157
158     set text [prune_gcc_output $text]
159
160     foreach p $additional_prunes {
161         if { [string length $p] > 0 } {
162             # Following regexp matches a complete line containing $p.
163             regsub -all "(^|\n)\[^\n\]*$p\[^\n\]*" $text "" text
164         }
165     }
166
167     # If we see "region xxx is full" then the testcase is too big for ram.
168     # This is tricky to deal with in a large testsuite like c-torture so
169     # deal with it here.  Just mark the testcase as unsupported.
170     if [regexp "(^|\n)\[^\n\]*: region \[^\n\]* is full" $text] {
171         # The format here is important.  See dg.exp.
172         return "::unsupported::memory full"
173     }
174
175     return $text
176 }
177
178 # Utility routines.
179
180 #
181 # search_for -- looks for a string match in a file
182 #
183 proc search_for { file pattern } {
184     set fd [open $file r]
185     while { [gets $fd cur_line]>=0 } {
186         if [string match "*$pattern*" $cur_line] then {
187             close $fd
188             return 1
189         }
190     }
191     close $fd
192     return 0
193 }
194
195 # Modified dg-runtest that can cycle through a list of optimization options
196 # as c-torture does.
197 proc gcc-dg-runtest { testcases default-extra-flags } {
198     global runtests
199
200     foreach test $testcases {
201         # If we're only testing specific files and this isn't one of
202         # them, skip it.
203         if ![runtest_file_p $runtests $test] {
204             continue
205         }
206
207         # Look for a loop within the source code - if we don't find one,
208         # don't pass -funroll[-all]-loops.
209         global torture_with_loops torture_without_loops
210         if [expr [search_for $test "for*("]+[search_for $test "while*("]] {
211             set option_list $torture_with_loops
212         } else {
213             set option_list $torture_without_loops
214         }
215
216         set nshort [file tail [file dirname $test]]/[file tail $test]
217
218         foreach flags $option_list {
219             verbose "Testing $nshort, $flags" 1
220             dg-test $test $flags ${default-extra-flags}
221         }
222     }
223 }
224
225 proc gcc-dg-debug-runtest { target_compile trivial opt_opts testcases } {
226     global srcdir subdir
227
228     if ![info exists DEBUG_TORTURE_OPTIONS] {
229         set DEBUG_TORTURE_OPTIONS ""
230         foreach type {-gdwarf-2 -gstabs -gstabs+ -gxcoff -gxcoff+ -gcoff} {
231             set comp_output [$target_compile \
232                     "$srcdir/$subdir/$trivial" "trivial.S" assembly \
233                     "additional_flags=$type"]
234             if { ! [string match "*: target system does not support the * debug format*" \
235                     $comp_output] } {
236                 foreach level {1 "" 3} {
237                     lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}"]
238                     foreach opt $opt_opts {
239                         lappend DEBUG_TORTURE_OPTIONS \
240                                 [list "${type}${level}" "$opt" ]
241                     }
242                 }
243             }
244         }
245     }
246
247     verbose -log "Using options $DEBUG_TORTURE_OPTIONS"
248
249     global runtests
250
251     foreach test $testcases {
252         # If we're only testing specific files and this isn't one of
253         # them, skip it.
254         if ![runtest_file_p $runtests $test] {
255             continue
256         }
257
258         set nshort [file tail [file dirname $test]]/[file tail $test]
259
260         foreach flags $DEBUG_TORTURE_OPTIONS {
261             set doit 1
262             if { [string match {*/debug-[126].c} "$nshort"] \
263                     && [string match "*1" [lindex "$flags" 0] ] } {
264                 set doit 0
265             }
266
267     # High optimization can remove the variable whose existence is tested.
268     # Dwarf debugging with commentary (-dA) preserves the symbol name in the
269     # assembler output, but stabs debugging does not.
270     # http://gcc.gnu.org/ml/gcc-regression/2003-04/msg00095.html
271             if { [string match {*/debug-[12].c} "$nshort"] \
272                     && [string match "*O*" "$flags"] \
273                     && ( [string match "*coff*" "$flags"] \
274                          || [string match "*stabs*" "$flags"] ) } {
275                 set doit 0
276             }
277
278             if { $doit } {
279                 verbose -log "Testing $nshort, $flags" 1
280                 dg-test $test $flags ""
281             }
282         }
283     }
284 }
285
286 # Prune any messages matching ARGS[1] (a regexp) from test output.
287 proc dg-prune-output { args } {
288     global additional_prunes
289
290     if { [llength $args] != 2 } {
291         error "[lindex $args 1]: need one argument"
292         return
293     }
294
295     lappend additional_prunes [lindex $args 1]
296 }
297
298 # Remove files matching the pattern from the build machine.
299 proc remove-build-file { pat } {
300     verbose "remove-build-file `$pat'" 2
301     set file_list "[glob -nocomplain $pat]"
302     verbose "remove-build-file `$file_list'" 2
303     foreach output_file $file_list {
304         remote_file build delete $output_file
305     }
306 }
307
308 # Remove compiler-generated coverage files for the current test.
309 proc cleanup-coverage-files { } {
310     # This assumes that we are two frames down from dg-test, and that
311     # it still stores the filename of the testcase in a local variable "name".
312     # A cleaner solution would require a new DejaGnu release.
313     upvar 2 name testcase
314     remove-build-file "[file rootname [file tail $testcase]].gc??"
315
316     # Clean up coverage files for additional source files.
317     if [info exists additional_sources] {
318         foreach srcfile $additional_sources {
319             remove-build-file "[file rootname [file tail $srcfile]].gc??"
320         }
321     }
322 }
323
324 # Remove compiler-generated files from -repo for the current test.
325 proc cleanup-repo-files { } {
326     # This assumes that we are two frames down from dg-test, and that
327     # it still stores the filename of the testcase in a local variable "name".
328     # A cleaner solution would require a new DejaGnu release.
329     upvar 2 name testcase
330     remove-build-file "[file rootname [file tail $testcase]].o"
331     remove-build-file "[file rootname [file tail $testcase]].rpo"
332
333     # Clean up files for additional source files.
334     if [info exists additional_sources] {
335         foreach srcfile $additional_sources {
336             remove-build-file "[file rootname [file tail $srcfile]].o"
337             remove-build-file "[file rootname [file tail $srcfile]].rpo"
338         }
339     }
340 }
341
342 # Remove compiler-generated RTL dump files for the current test.
343 #
344 # SUFFIX is the filename suffix pattern.
345 proc cleanup-rtl-dump { suffix } {
346     # This assumes that we are two frames down from dg-test, and that
347     # it still stores the filename of the testcase in a local variable "name".
348     # A cleaner solution would require a new DejaGnu release.
349     upvar 2 name testcase
350     remove-build-file "[file tail $testcase].??.$suffix"
351
352     # Clean up dump files for additional source files.
353     if [info exists additional_sources] {
354         foreach srcfile $additional_sources {
355             remove-build-file "[file tail $srcfile].??.$suffix"
356         }
357     }
358 }
359
360 # Remove a specific tree dump file for the current test.
361 #
362 # SUFFIX is the file suffix pattern.
363 proc cleanup-tree-dump { suffix } {
364     # This assumes that we are two frames down from dg-test, and that
365     # it still stores the filename of the testcase in a local variable "name".
366     # A cleaner solution would require a new dejagnu release.
367     upvar 2 name testcase
368     remove-build-file "[file tail $testcase].t??.$suffix"
369
370     # Clean up dump files for additional source files.
371     if [info exists additional_sources] {
372         foreach srcfile $additional_sources {
373             remove-build-file "[file tail $srcfile].t??.$suffix"
374         }
375     }
376 }
377
378 # Remove files kept by --save-temps for the current test.
379 #
380 # Currently this is only .i files, but more can be added if there are
381 # tests generating them.
382 proc cleanup-saved-temps { } {
383     global additional_sources
384
385     # This assumes that we are two frames down from dg-test, and that
386     # it still stores the filename of the testcase in a local variable "name".
387     # A cleaner solution would require a new DejaGnu release.
388     upvar 2 name testcase
389     remove-build-file "[file rootname [file tail $testcase]].ii"
390     remove-build-file "[file rootname [file tail $testcase]].i"
391
392     # Clean up saved temp files for additional source files.
393     if [info exists additional_sources] {
394         foreach srcfile $additional_sources {
395             remove-build-file "[file rootname [file tail $srcfile]].ii"
396             remove-build-file "[file rootname [file tail $srcfile]].i"
397         }
398     }
399 }
400
401 # We need to make sure that additional_* are cleared out after every
402 # test.  It is not enough to clear them out *before* the next test run
403 # because gcc-target-compile gets run directly from some .exp files
404 # (outside of any test).  (Those uses should eventually be eliminated.)
405
406 # Because the DG framework doesn't provide a hook that is run at the
407 # end of a test, we must replace dg-test with a wrapper.
408
409 if { [info procs saved-dg-test] == [list] } {
410     rename dg-test saved-dg-test
411
412     proc dg-test { args } {
413         global additional_files
414         global additional_sources
415         global additional_prunes
416         global errorInfo
417         global compiler_conditional_xfail_data
418
419         if { [ catch { eval saved-dg-test $args } errmsg ] } {
420             set saved_info $errorInfo
421             set additional_files ""
422             set additional_sources ""
423             set additional_prunes ""
424             if [info exists compiler_conditional_xfail_data] {
425                 unset compiler_conditional_xfail_data
426             }
427             error $errmsg $saved_info
428         }
429         set additional_files ""
430         set additional_sources ""
431         set additional_prunes ""
432         if [info exists compiler_conditional_xfail_data] {
433             unset compiler_conditional_xfail_data
434         }
435     }
436 }
437
438 set additional_prunes ""