aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/lib/compat.exp
blob: 2926d0be680b8ade0ca4afece27f1141e97036c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# Copyright (C) 2002 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

# This file was written by Janis Johnson, <janis187@us.ibm.com>


# Test interoperability of two compilers that follow the same ABI, or
# compatibility of two versions of GCC.
#
# Each test has a main program that does nothing but call a function,
# plus two additional source files that contain parts of a program that
# rely on the ABI.  those source files are compiled into relocatable
# object files with both compilers.  Executables are built using various
# combinations of those object files, with the main program compiled
# with the compiler under test and using that compiler's runtime support.

# The including .exp file must define these callback procedures.
if [string match "" [info procs "compat-use-alt-compiler"]] then {
    error "Proc compat-use-alt-compiler is not defined."
}
if [string match "" [info procs "compat-use-tst-compiler"]] then {
    error "Proc compat-use-tst-compiler is not defined."
}

# Each test is run with each pair of compiler options from this list.
# The first set of options in each pair is used by the compiler under
# test, and the second set is used by the alternate compiler.
# The default option lists can be overridden by
# COMPAT_OPTIONS="[list [list {tst_1} {alt_1}]...[list {tst_n} {alt_n}]]"
# where tst_i and alt_i are lists of options.  You can put this in the
# environment before site.exp is written or add it to site.exp directly.
if ![info exists COMPAT_OPTIONS] {
    set COMPAT_OPTIONS [list \
	[list {} {}]]
}

set option_list $COMPAT_OPTIONS

load_lib dg.exp

#
# compat-obj -- compile to an object file
#
# SOURCE is the source file
# DEST is the object file
# OPTALL is the list of compiler options to use with all tests
# OPTFILE is the list of compiler options to use with this file
# OPTSTR is the options to print with test messages
#
proc compat-obj { source dest optall optfile optstr } {
    global testcase
    global tool

    # Set up the options for compiling this file.
    set options ""
    lappend options "additional_flags=$optfile $optall"

    set comp_output [${tool}_target_compile "$source" "$dest" object $options]
    ${tool}_check_compile "$testcase $dest compile" $optstr $dest $comp_output
}

# compat-run -- link and run an executable
#
# TESTNAME is the mixture of object files to link
# OBJLIST is the list of object files to link
# DEST is the name of the executable
# OPTALL is a list of compiler and linker options to use for all tests
# OPTFILE is a list of compiler and linker options to use for this test
# OPTSTR is the list of options to list in messages
#
proc compat-run { testname objlist dest optall optfile optstr } {
    global testcase
    global tool

    # Check that all of the objects were built successfully.
    foreach obj [split $objlist] {
	if ![file exists $obj] then {
	    unresolved "$testcase $testname link $optstr"
	    unresolved "$testcase $testname execute $optstr"
	    return
	}
    }

    # Set up the options for linking this test.
    set options ""
    lappend options "additional_flags=$optfile $optall"

    # Link the objects into an executable.
    set comp_output [${tool}_target_compile "$objlist" $dest executable \
		     "$options"]
    if ![${tool}_check_compile "$testcase $testname link" "" \
	 $dest $comp_output] then {
	unresolved "$testcase $testname execute $optstr"
	return
    }

    # Run the self-checking executable.
    if ![string match "*/*" $dest] then {
	set dest "./$dest"
    }
    set result [${tool}_load $dest "" ""]
    set status [lindex $result 0]
    if { $status == "pass" } then {
	remote_file build delete $dest
    }
    $status "$testcase $testname execute $optstr"
}

#
# compat-flags -- get special tool flags to use for a source file
#
# SRC is the full patchname of the source file.
# The result is a list of options to use.
#
# This code is copied from proc dg-test in dg.exp from DejaGNU.
#
proc compat-get-options { src } {
    # Define our own special function `unknown` so we catch spelling errors.
    # But first rename the existing one so we can restore it afterwards.
    catch {rename dg-save-unknown ""}
    rename unknown dg-save-unknown
    proc unknown { args } {
	return -code error "unknown dg option: $args"
    }

    # dg-options sets a variable called dg-extra-tool-flags.
    set dg-extra-tool-flags ""
    set tmp [dg-get-options $src]
    foreach op $tmp {
	set cmd [lindex $op 0]
	if ![string compare "dg-options" $cmd] {
	    set status [catch "$op" errmsg]
	    if { $status != 0 } {
		perror "src: $errmsg for \"$op\"\n"
		unresolved "$src: $errmsg for \"$op\""
		return
	    }
	} else {
	    # Ignore unrecognized dg- commands, but warn about them.
	    warning "compat.exp does not support $cmd"
	}
    }

    # Restore normal error handling.
    rename unknown ""
    rename dg-save-unknown unknown

    return ${dg-extra-tool-flags}
}

#
# compat-execute -- compile with compatible compilers
#
# SRC1 is the full pathname of the main file of the testcase.
# SID identifies a test suite in the names of temporary files.
# USE_ALT is nonzero if we're using an alternate compiler as well as
#   the compiler under test.
#
proc compat-execute { src1 sid use_alt } {
    global srcdir tmpdir
    global option_list
    global tool
    global verbose
    global testcase
    global gluefile

    # Set up the names of the other source files.
    regsub "_main.*" $src1 "" base
    regsub ".*/" $base "" base
    regsub "_main" $src1 "_x" src2
    regsub "_main" $src1 "_y" src3

    # Use the dg-options mechanism to specify extra flags for this test. 
    # The extra flags in each file are used to compile that file, and the
    # extra flags in *_main.* are also used for linking.
    set extra_flags_1 [compat-get-options $src1]
    set extra_flags_2 [compat-get-options $src2]
    set extra_flags_3 [compat-get-options $src3]

    # Define the names of the object files.
    regsub "sid" "sid_main_tst.o" $sid obj1
    regsub "sid" "sid_x_tst.o" $sid obj2_tst
    regsub "sid" "sid_x_alt.o" $sid obj2_alt
    regsub "sid" "sid_y_tst.o" $sid obj3_tst
    regsub "sid" "sid_y_alt.o" $sid obj3_alt

    # Get the base name of this test, for use in messages.
    regsub "^$srcdir/?" $src1 "" testcase
    regsub "_main.*" $testcase "" testcase
    # Set up the base name of executable files so they'll be unique.
    regsub -all "\[./\]" $testcase "-" execbase

    # If we couldn't rip $srcdir out of `src1' then just do the best we can.
    # The point is to reduce the unnecessary noise in the logs.  Don't strip
    # out too much because different testcases with the same name can confuse
    # `test-tool'.
    if [string match "/*" $testcase] then {
        set testcase "[file tail [file dirname $src1]]/[file tail $src1]"
    }

    # Loop through all of the option lists used for this test.

    set count 0
    foreach option_pair $option_list {

	# Pick out each set of options.
	set tst_option [lindex $option_pair 0]
	set alt_option [lindex $option_pair 1]
	set optstr ""
	if { ![string match $tst_option ""] \
	     || ![string match $alt_option ""] } then {
	    set optstr "\"$tst_option\",\"$alt_option\""
	}
	verbose "Testing $testcase, $optstr" 1

	# There's a unique name for each executable we generate, based on
	# the set of options and how the pieces of the tests are compiled.
	set execname1 "${execbase}-${count}1"
	set execname2 "${execbase}-${count}2"
	set execname3 "${execbase}-${count}3"
	set execname4 "${execbase}-${count}4"
	incr count

	remote_file build delete $execname1
	remote_file build delete $execname2
	remote_file build delete $execname3
	remote_file build delete $execname4

	# Compile pieces with the alternate compiler; we'll catch problems
	# later.  Skip this if we don't have an alternate compiler.
	if { $use_alt != 0 } then {
	    compat-use-alt-compiler
	    compat-obj "$src2" "$obj2_alt" $alt_option $extra_flags_2 $optstr
	    compat-obj "$src3" "$obj3_alt" $alt_option $extra_flags_3 $optstr
	}

	# Compile pieces with the compiler under test.
	compat-use-tst-compiler
	compat-obj "$src1" "$obj1" $tst_option $extra_flags_1 $optstr
	compat-obj "$src2" "$obj2_tst" $tst_option $extra_flags_2 $optstr
	compat-obj "$src3" "$obj3_tst" $tst_option $extra_flags_3 $optstr

	# Link (using the compiler under test), run, and clean up tests.
	compat-run "${obj2_tst}-${obj3_tst}" \
	    "$obj1 $obj2_tst $obj3_tst" $execname1 \
	    $tst_option $extra_flags_1 $optstr

	# If we've got an alternate compiler try some combinations.
	if { $use_alt != 0 } then {
	    compat-run "${obj2_tst}-${obj3_alt}" "$obj1 $obj2_tst $obj3_alt" \
		       $execname2 $tst_option $extra_flags_1 $optstr
	    compat-run "${obj2_alt}-${obj3_tst}" "$obj1 $obj2_alt $obj3_tst" \
		       $execname3 $tst_option $extra_flags_1 $optstr
	    compat-run "${obj2_alt}-${obj3_alt}" "$obj1 $obj2_alt $obj3_alt" \
		       $execname4 $tst_option $extra_flags_1 $optstr
	}

	# Clean up object files.
	set files [glob -nocomplain ${sid}_*.o]
	if { $files != "" } {
	    foreach objfile $files {
		if { ![info exists gluefile] || $objfile != $gluefile } {
		    eval "remote_file build delete $objfile"
		}
	    }
	}
    }
}