1# libstdc++ "tool init file" for DejaGNU
2
3# Copyright (C) 2001-2019 Free Software Foundation, Inc.
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 3 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; see the file COPYING3.  If not see
17# <http://www.gnu.org/licenses/>.
18
19
20# Define callbacks and load other libraries.  This file is loaded relatively
21# early, and before any other file we write ourselves.  "load_lib" will
22# find anything in the DejaGNU installation tree, or in our lib directory.
23# "load_gcc_lib" will search the core compiler's .exp collection instead.
24#
25# The naming rule is that dg.exp looks for "tool-" and runtest.exp looks
26# for "tool_" when finding callbacks.  Utility routines we define for
27# our callbacks begin with "v3-".
28#
29# libstdc++_* callbacks we don't define, but could:
30# ..._option_help           prints additional --help output
31# ..._option_proc (--foo)   process our own options
32# ..._init (normal.exp)     called once per test file
33# ..._finish                bracketing function for libstdc++_init
34# ...-dg-prune              removing output text, see top of system dg.exp
35#
36# Useful hook:  if ${hostname}_init exists, it will be called, almost
37# the last thing before testing begins.  This can be defined in, e.g.,
38# ~/.dejagnurc or $DEJAGNU.
39
40proc load_gcc_lib { filename } {
41    global srcdir loaded_libs
42
43    load_file $srcdir/../../gcc/testsuite/lib/$filename
44    set loaded_libs($filename) ""
45}
46
47# system routines
48load_lib dg.exp
49load_lib libgloss.exp
50# compiler routines, then ours
51load_gcc_lib target-supports.exp
52load_gcc_lib target-supports-dg.exp
53load_lib prune.exp
54load_lib dg-options.exp
55load_gcc_lib scanasm.exp
56load_gcc_lib target-libpath.exp
57load_gcc_lib timeout.exp
58load_gcc_lib timeout-dg.exp
59load_gcc_lib wrapper.exp
60load_gcc_lib target-utils.exp
61
62# Useful for debugging.  Pass the name of a variable and the verbosity
63# threshold (number of -v's on the command line).
64proc v3track { var n } {
65    upvar $var val
66    verbose "++ $var is $val" $n
67}
68
69# Copy file to the target.
70proc v3-copy-file {src dst} {
71    if { [catch { set symlink [file readlink $src] } x] } then {
72	remote_download target $src $dst
73    } else {
74	if { [regexp "^/" "$symlink"] } then {
75	    remote_download target $symlink $dst
76	} else {
77	    set dirname [file dirname $f]
78	    remote_download target $dirname/$symlink $dst
79	}
80    }
81}
82
83# Called by v3-init below.  "Static" to this file.
84proc v3-copy-files {srcfiles} {
85    foreach f $srcfiles {
86	v3-copy-file $f [file tail $f]
87    }
88}
89
90# Called once, during runtest.exp setup.
91proc libstdc++_init { testfile } {
92    global env
93    global v3-sharedlib v3-libgomp
94    global srcdir blddir objdir tool_root_dir
95    global cc cxx cxxflags cxxpchflags cxxldflags cxxvtvflags
96    global includes
97    global gluefile wrap_flags
98    global ld_library_path
99    global target_triplet
100    global flags_file
101    global tool_timeout
102    global DEFAULT_CXXFLAGS
103    global STATIC_LIBCXXFLAGS
104
105    # We set LC_ALL and LANG to C so that we get the same error
106    # messages as expected.
107    setenv LC_ALL C
108    setenv LANG C
109
110    # LANGUAGE changes the behavior of GNU gettext(3) and causes
111    # std::messages tests to fail.
112    array unset env LANGUAGE
113
114    # Many hosts now default to a non-ASCII C locale, however, so
115    # they can set a charset encoding here if they need.
116    if { [ishost "*-*-cygwin*"] } {
117      setenv LC_ALL C.ASCII
118      setenv LANG C.ASCII
119    }
120
121    set blddir [lookfor_file [get_multilibs] libstdc++-v3]
122    set flags_file "${blddir}/scripts/testsuite_flags"
123    set shlib_ext [get_shlib_extension]
124    v3track flags_file 2
125
126    # If a test doesn't have special options, use DEFAULT_CXXFLAGS.
127    # Use this variable if the behavior
128    #   1) only applies to libstdc++ testing
129    #   2) might need to be negated
130    # In particular, some tests have to be run without precompiled
131    # headers, or without assertions.
132
133    if ![info exists DEFAULT_CXXFLAGS] then {
134	set DEFAULT_CXXFLAGS ""
135	# Host specific goo here.
136	if { [string match "powerpc-*-darwin*" $target_triplet] } {
137	    append DEFAULT_CXXFLAGS " -multiply_defined suppress"
138	}
139	if { [string match "powerpc-ibm-aix*" $target_triplet] } {
140	    append DEFAULT_CXXFLAGS " -Wl,-bmaxdata:0x20000000"
141	}
142    }
143    v3track DEFAULT_CXXFLAGS 2
144
145    # By default, we assume we want to run program images.
146    global dg-do-what-default
147    set dg-do-what-default run
148
149    # Copy any required data files.
150    v3-copy-files [glob -nocomplain "$srcdir/data/*.tst"]
151    v3-copy-files [glob -nocomplain "$srcdir/data/*.txt"]
152
153    set ld_library_path_tmp ""
154
155    # Locate libgcc.a so we don't need to account for different values of
156    # SHLIB_EXT on different platforms
157    set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
158    if {$gccdir != ""} {
159	set gccdir [file dirname $gccdir]
160	append ld_library_path_tmp ":${gccdir}"
161    }
162    v3track gccdir 3
163
164    # Locate libatomic.
165    set v3-libatomic 0
166    set libatomicdir [lookfor_file $blddir/../libatomic .libs/libatomic.$shlib_ext]
167    if {$libatomicdir != ""} {
168	set v3-libatomic 1
169	set libatomicdir [file dirname $libatomicdir]
170	append ld_library_path_tmp ":${libatomicdir}"
171	verbose -log "libatomic support detected"
172    }
173    v3track libatomicdir 3
174
175    # Locate libgomp. This is only required for parallel mode.
176    set v3-libgomp 0
177    set libgompdir [lookfor_file $blddir/../libgomp .libs/libgomp.$shlib_ext]
178    if {$libgompdir != ""} {
179	set v3-libgomp 1
180	set libgompdir [file dirname $libgompdir]
181	append ld_library_path_tmp ":${libgompdir}"
182	verbose -log "libgomp support detected"
183    }
184    v3track libgompdir 3
185
186    # Locate libvtv. This is only required for --enable-vtable-verify.
187    set v3-libvtv 0
188    set libvtvdir [lookfor_file $blddir/../libvtv .libs/libvtv.$shlib_ext]
189    if {$libvtvdir != ""} {
190	set v3-libvtv 1
191	set libvtvdir [file dirname $libvtvdir]
192	append ld_library_path_tmp ":${libvtvdir}"
193	verbose -log "libvtv support detected"
194    }
195    v3track libvtvdir 3
196
197    # Locate libstdc++ shared library. (ie libstdc++.so.)
198    set v3-sharedlib 0
199    set sharedlibdir [lookfor_file $blddir src/.libs/libstdc++.$shlib_ext]
200    if {$sharedlibdir != ""} {
201	if { ([string match "*-*-gnu*" $target_triplet]
202	      || [string match "*-*-linux*" $target_triplet]
203	      || [string match "*-*-solaris*" $target_triplet])
204	     && [isnative] } then {
205	    set v3-sharedlib 1
206	    verbose -log "shared library support detected"
207	}
208    }
209    v3track v3-sharedlib 3
210
211    set STATIC_LIBCXXFLAGS ""
212    set staticlibdir [lookfor_file $blddir src/.libs/libstdc++.a]
213    if {$staticlibdir != ""} {
214	set staticlibdir [file dirname $staticlibdir]
215	# Some targets use libstdc++.a%s in their specs, so they need a
216	# -B option for uninstalled testing.
217	set STATIC_LIBCXXFLAGS " -B${staticlibdir} "
218    }
219
220    # Compute what needs to be added to the existing LD_LIBRARY_PATH.
221    if {$gccdir != ""} {
222	set compiler ${gccdir}/xg++
223	set ld_library_path ${ld_library_path_tmp}
224	append ld_library_path ":${blddir}/src/.libs"
225
226	if { [is_remote host] == 0 && [which $compiler] != 0 } {
227	  foreach i "[exec $compiler --print-multi-lib]" {
228	    set mldir ""
229	    regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
230	    set mldir [string trimright $mldir "\;@"]
231	    if { "$mldir" == "." } {
232	      continue
233	    }
234	    if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } {
235	      append ld_library_path ":${gccdir}/${mldir}"
236	    }
237	  }
238	}
239
240	set_ld_library_path_env_vars
241	if [info exists env(LD_LIBRARY_PATH)] {
242	  verbose -log "LD_LIBRARY_PATH = $env(LD_LIBRARY_PATH)"
243	}
244    } else {
245	set compiler [transform "g++"]
246    }
247
248    # Set the default timeout for v3 tests.
249    set tool_timeout 600
250
251    # Default settings.
252    set cxx [transform "g++"]
253    set cxxflags "-fmessage-length=0 -fno-show-column"
254    set cxxpchflags ""
255    set cxxvtvflags ""
256    set cxxldflags ""
257    set cc [transform "gcc"]
258    # Locate testsuite_hooks.h and other testsuite headers.
259    set includes "-I${srcdir}/util"
260    # Adapt the defaults for special circumstances.
261    if [is_remote host] {
262	# A remote host does not, in general, have access to the
263	# $srcdir so we copy the testsuite headers into the current
264	# directory, and then add that to the search path.
265	foreach src [glob "${srcdir}/util/*.h" \
266			  "${srcdir}/util/*.cc" \
267			  "${srcdir}/util/*.tcc" \
268			  "${srcdir}/util/*.hpp" \
269			  "${srcdir}/util/*/*.h" \
270			  "${srcdir}/util/*/*.cc" \
271			  "${srcdir}/util/*/*.tcc" \
272			  "${srcdir}/util/*/*.hpp" \
273			  "${srcdir}/util/*/*/*.h" \
274			  "${srcdir}/util/*/*/*.cc" \
275			  "${srcdir}/util/*/*/*.tcc" \
276			  "${srcdir}/util/*/*/*.hpp" \
277			  "${srcdir}/util/*/*/*/*.h" \
278			  "${srcdir}/util/*/*/*/*.cc" \
279			  "${srcdir}/util/*/*/*/*.tcc" \
280			  "${srcdir}/util/*/*/*/*.hpp" \
281			  "${srcdir}/util/*/*/*/*/*.h" \
282			  "${srcdir}/util/*/*/*/*/*.cc" \
283			  "${srcdir}/util/*/*/*/*/*.tcc" \
284			  "${srcdir}/util/*/*/*/*/*.hpp" ] {
285	    # Remove everything up to "util/..."
286	    set dst [string range $src [string length "${srcdir}/"] end]
287	    # Create the directory containing the file.
288	    set dir [file dirname $dst]
289	    remote_exec host "mkdir" [list "-p" "$dir"]
290	    # Download the file.
291	    set result [remote_download host $src $dst]
292	    if { $result == "" } {
293		verbose -log "Unable to download ${srcdir}/${src} to host."
294		return "untested"
295	    }
296	}
297	set includes "-Iutil"
298    } elseif { [file exists $flags_file] } {
299	# If we find a testsuite_flags file, we're testing in the build dir.
300	set cxx [exec sh $flags_file --build-cxx]
301	set cxxflags [exec sh $flags_file --cxxflags]
302	set cxxpchflags [exec sh $flags_file --cxxpchflags]
303	set cxxvtvflags [exec sh $flags_file --cxxvtvflags]
304	set cxxldflags [exec sh $flags_file --cxxldflags]
305	set cc [exec sh $flags_file --build-cc]
306	set includes [exec sh $flags_file --build-includes]
307    }
308    append cxxflags " "
309    append cxxflags [getenv CXXFLAGS]
310
311    if ![regexp ".*-O" $cxxflags] {
312	append cxxflags " -g -O2"
313    }
314
315    v3track cxxflags 2
316
317    # Should be as good as -fdiagnostics-color=never, but more compatible
318    setenv GCC_COLORS ""
319    # Always use MO files built by this test harness.
320    set ccflags "$cxxflags -DLOCALEDIR=\".\""
321    set cxxflags "$cxxflags -DLOCALEDIR=\".\""
322
323    # If a PCH file is available, use it.  We must delay performing
324    # this check until $cxx and such have been initialized because we
325    # perform a test compilation.  (Ideally, gcc --print-file-name would
326    # list PCH files, but it does not.)
327    if { $cxxpchflags != "" } {
328	set src "config[pid].cc"
329	set f [open $src "w"]
330	puts $f "int main () {}"
331	close $f
332
333	# Fixme: "additional_flags=$cxxpchflags" fails, but would be
334	# useful as then the requested variant of the pre-build PCH
335	# files could be tested to see if it works.
336	set lines [v3_target_compile $src "config[pid].o" object \
337		   "additional_flags=-include additional_flags=bits/stdc++.h"]
338	if { $lines != "" } {
339	    verbose -log "Requested PCH file: $cxxpchflags"
340	    verbose -log "is not working, and will not be used."
341	    set cxxpchflags ""
342	}
343	file delete $src
344     }
345    v3track cxxpchflags 2
346
347    global PCH_CXXFLAGS
348    if ![info exists PCH_CXXFLAGS] then {
349	set PCH_CXXFLAGS $cxxpchflags
350	v3track PCH_CXXFLAGS 2
351    }
352
353    libstdc++_maybe_build_wrapper "${objdir}/testglue.o" "-fexceptions"
354}
355
356# Callback for cleanup routines.
357proc libstdc++_exit { } {
358    global gluefile;
359
360    if [info exists gluefile] {
361	file_on_build delete $gluefile;
362	unset gluefile;
363    }
364}
365
366# Callback from system dg-test.
367proc libstdc++-dg-test { prog do_what extra_tool_flags } {
368    # Set up the compiler flags, based on what we're going to do.
369    switch $do_what {
370	"preprocess" {
371	    set compile_type "preprocess"
372	    set output_file "[file rootname [file tail $prog]].i"
373	}
374	"compile" {
375	    set compile_type "assembly"
376	    set output_file "[file rootname [file tail $prog]].s"
377	}
378	"assemble" {
379	    set compile_type "object"
380	    set output_file "[file rootname [file tail $prog]].o"
381	}
382	"link" {
383	    set compile_type "executable"
384	    set output_file "./[file rootname [file tail $prog]].exe"
385	}
386	"run" {
387	    set compile_type "executable"
388	    # FIXME: "./" is to cope with "." not being in $PATH.
389	    # Should this be handled elsewhere?
390	    # YES.
391	    set output_file "./[file rootname [file tail $prog]].exe"
392	    # This is the only place where we care if an executable was
393	    # created or not.  If it was, dg.exp will try to run it.
394	    catch { remote_file build delete $output_file }
395	}
396	default {
397	    perror "$do_what: not a valid dg-do keyword"
398	    return ""
399	}
400    }
401
402    # Short-circut a bunch of complicated goo here for the special
403    # case of compiling a test file as a "C" file, not as C++. Why? So
404    # -nostdc++ doesn't trip us up. So all the extra object files
405    # don't trip us up. So automatically linking in libstdc++ doesn't
406    # happen. So CXXFLAGS don't error.
407    set select_compile "v3_target_compile"
408    set options ""
409    if { $extra_tool_flags != "" } {
410	verbose -log "extra_tool_flags are:"
411	verbose -log $extra_tool_flags
412	if { [string first "-x c" $extra_tool_flags ] != -1 } {
413	    verbose -log "compiling and executing as C, not C++"
414	    set edit_tool_flags $extra_tool_flags
415	    regsub -all ".x c" $edit_tool_flags "" edit_tool_flags
416	    lappend options "additional_flags=$edit_tool_flags"
417	    set select_compile "v3_target_compile_as_c"
418	} else {
419	    lappend options "additional_flags=$extra_tool_flags"
420	}
421    }
422
423    # There is a libstdc++_compile made for us by default (via the tool-
424    # and-target file), but the defaults are lacking in goodness.
425    set comp_output [$select_compile "$prog" "$output_file" "$compile_type" $options];
426
427    set unsupported_message [libstdc++_check_unsupported_p $comp_output]
428    if { $unsupported_message != "" } {
429	set comp_output "::unsupported::$unsupported_message"
430    }
431
432    return [list $comp_output $output_file]
433}
434
435# Override the DejaGnu dg-test in order to clear flags after a test, as
436# is done for compiler tests in gcc-dg.exp.
437
438if { [info procs saved-dg-test] == [list] } {
439    rename dg-test saved-dg-test
440
441    proc dg-test { args } {
442	global additional_prunes
443	global errorInfo
444	global testname_with_flags
445
446	if { [ catch { eval saved-dg-test $args } errmsg ] } {
447	    set saved_info $errorInfo
448	    set additional_prunes ""
449	    if [info exists testname_with_flags] {
450		unset testname_with_flags
451	    }
452	    unset_timeout_vars
453	    error $errmsg $saved_info
454	}
455	set additional_prunes ""
456	unset_timeout_vars
457	if [info exists testname_with_flags] {
458	    unset testname_with_flags
459	}
460    }
461}
462
463# True if the library supports wchar_t.
464set v3-wchar_t 0
465
466# True if the library supports threads.
467set v3-threads 0
468
469# True if the library supports symbol versioning.
470set v3-symver 0
471
472# Called from libstdc++-dg-test above.  Calls back into system's
473# target_compile to actually do the work.
474proc v3_target_compile { source dest type options } {
475    global gluefile
476    global wrap_flags
477    global cxx
478    global cxxflags
479    global cxxvtvflags
480    global cxxldflags
481    global includes
482    global STATIC_LIBCXXFLAGS
483    global tool
484
485    lappend options "additional_flags=-fno-diagnostics-show-caret -fdiagnostics-color=never"
486
487    if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } {
488	lappend options "libs=${gluefile}"
489	lappend options "ldflags=${wrap_flags}"
490    }
491
492    set cxx_final $cxx
493    set cxxlibglossflags  [libgloss_link_flags]
494    set cxx_final [concat $cxx_final $cxxlibglossflags]
495    set cxx_final [concat $cxx_final $STATIC_LIBCXXFLAGS]
496    set cxx_final [concat $cxx_final $cxxflags]
497    set cxx_final [concat $cxx_final $cxxvtvflags]
498    set cxx_final [concat $cxx_final $includes]
499
500    # Flag setting based on type argument.
501    if { $type == "executable" } {
502	# Link the support objects into executables.
503	lappend options "additional_flags=./libtestc++.a $cxxldflags"
504    } else {
505	if { $type == "sharedlib" } {
506	    # Don't link in anything.
507	    set type "executable"
508	}
509    }
510
511    lappend options "compiler=$cxx_final"
512    lappend options "timeout=[timeout_value]"
513
514    set comp_output [target_compile $source $dest $type $options]
515
516    return $comp_output
517}
518
519
520# Called from libstdc++-dg-test above, but only for "C" compilation.
521# Calls back into system's target_compile to actually do the work.
522proc v3_target_compile_as_c { source dest type options } {
523    global gluefile
524    global wrap_flags
525    global includes
526    global flags_file
527    global blddir
528    global cc
529    global cxxflags
530    global STATIC_LIBCXXFLAGS
531    global tool
532
533    if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } {
534	lappend options "libs=${gluefile}"
535	lappend options "ldflags=${wrap_flags}"
536    }
537
538    set tname [target_info name]
539    set cc_final $cc
540    set cxxlibglossflags [libgloss_link_flags]
541    set cc_final [concat $cc_final $cxxlibglossflags]
542    set cc_final [concat $cc_final $STATIC_LIBCXXFLAGS]
543    set cc_final [concat $cc_final $cxxflags]
544    set cc_final [concat $cc_final $includes]
545    regsub -all {\s[-]nostdinc[+][+]} $cc_final "" cc_final
546
547    # This is needed for "C" tests, as this type of test may need the
548    # C++ includes. And if we're not testing in the build directory,
549    # the includes variable is not likely to include the necessary
550    # info.
551    if { ![file exists $flags_file] } {
552	# ??? We need a --print-include-dirs option to GCC, so that
553	# we can avoid these hacks.  The heuristics here will not
554	# work with non-standard --with-includedir= options.
555	set version [remote_exec host ${cc} -dumpversion]
556	# Remove the trailing newline from the output.
557	set version [string trimright [lindex $version 1]]
558	set machine [remote_exec host ${cc} -dumpmachine]
559	set machine [string trimright [lindex $machine 1]]
560	set comp_base_dir [remote_exec host ${cc} --print-prog-name=cc1]
561	set comp_base_dir [lindex $comp_base_dir 1]
562	set comp_base_dir [file dirname [file dirname [file dirname [file dirname [file dirname $comp_base_dir]]]]]
563	# For a cross compiler, the header files will be located in a
564	# machine-specific subdirectory.
565	set crossbase "${comp_base_dir}/${machine}/include/c++/${version}"
566	set crosstarget "${crossbase}/${machine}"
567	set cc_final [concat $cc_final "-I$crossbase -I$crosstarget"]
568	# For a native compiler, the header files will be located at
569	# the top level.
570	set includesbase "${comp_base_dir}/include/c++/${version}"
571	set includestarget "${includesbase}/${machine}"
572	set cc_final [concat $cc_final "-I$includesbase -I$includestarget"]
573
574	set libdir "-L${comp_base_dir}/lib"
575    } else {
576	set libdir "-L${blddir}/libsupc++/.libs"
577	set libdir [concat $libdir "-L${blddir}/src/.libs"]
578    }
579
580    set cc_final [concat $cc_final "$libdir"]
581
582    lappend options "compiler=$cc_final"
583    lappend options "timeout=[timeout_value]"
584
585    set comp_output [target_compile $source $dest $type $options]
586
587    return $comp_output
588}
589
590# Build the support objects linked in with the libstdc++ tests.  In
591# addition, set v3-wchar_t, v3-threads, and v3-symver appropriately.
592proc v3-build_support { } {
593    global env
594    global srcdir
595    global v3-wchar_t
596    global v3-threads
597    global v3-symver
598    global v3-sharedlib
599
600    # Figure out whether or not the library supports certain features.
601    set v3-wchar_t 0
602    set v3-threads 0
603    set v3-symver 0
604    set libtest_objs ""
605
606    set config_src "config.cc"
607    set config_out "config.ii"
608    set f [open $config_src "w"]
609    puts $f "#include <bits/c++config.h>"
610    puts $f "#include <bits/gthr.h>"
611    close $f
612    v3_target_compile $config_src $config_out preprocess "additional_flags=-dN"
613    set file [open $config_out r]
614    set preprocessed [read $file]
615    close $file
616    if { [string first "_GLIBCXX_USE_WCHAR_T" $preprocessed] != -1 } {
617	verbose -log "wchar_t support detected"
618	set v3-wchar_t 1
619    }
620    if { [string first "_GLIBCXX_SYMVER" $preprocessed] != -1 } {
621	verbose -log "symbol versioning support detected"
622	set v3-symver 1
623    }
624    if { [string first "__GTHREADS" $preprocessed] != -1 } {
625	verbose -log "thread support detected"
626	set v3-threads 1
627    }
628
629    # Try to build the MO files that are used by some of the locale
630    # tests.  If we can't build them, that's OK; it just means that
631    # those tests will fail.
632    foreach lang [list "fr" "de"] {
633	catch {
634	    file mkdir "$lang/LC_MESSAGES"
635	    remote_exec "build" "msgfmt" "-o $lang/LC_MESSAGES/libstdc++.mo $srcdir/../po/$lang.po"
636	    if [is_remote host] {
637		remote_exec "host" "mkdir" "-p $lang/LC_MESSAGES"
638		remote_download "host" "$lang/LC_MESSAGES/libstdc++.mo" "$lang/LC_MESSAGES/libstdc++.mo"
639	    }
640	}
641    }
642
643    # Build the support objects.
644    set source_files [list testsuite_abi.cc testsuite_allocator.cc \
645			  testsuite_character.cc testsuite_hooks.cc \
646			  io/verified_cmd_line_input.cc \
647			  io/prog_bar.cc performance/time/elapsed_timer.cc ]
648    foreach f $source_files {
649	set obj [file rootname $f].o
650	set object_file [file tail $obj]
651	# Compile with "-w" so that warnings issued by the compiler
652	# do not prevent compilation.
653	# Disable LTO so that ar/ranlib don't need the LTO plugin.
654	if { [v3_target_compile $srcdir/util/$f $object_file "object" \
655		  [list "incdir=$srcdir" "additional_flags=-w -fno-lto"]]
656	     != "" } {
657	    error "could not compile $f"
658	}
659	append libtest_objs "$object_file "
660    }
661
662    # Collect into libtestc++.a
663    if  [info exists env(AR)] {
664	set ar $env(AR)
665    } else {
666	set ar [transform "ar"]
667    }
668    set arargs "-rc ./libtestc++.a ${libtest_objs}"
669    verbose -log "$ar $arargs"
670    set result [lindex [remote_exec host "$ar" "$arargs"] 0]
671    verbose "link result is $result"
672    if { $result == 0 } {
673	if  [info exists env(RANLIB)] {
674	    set ranlib $env(RANLIB)
675	} else {
676	    set ranlib [transform "ranlib"]
677	}
678	set ranlibargs "./libtestc++.a"
679	verbose -log "$ranlib $ranlibargs"
680	set result [lindex [remote_exec host "$ranlib" "$ranlibargs"] 0]
681	if { $result != 0 } {
682	    error "could not link libtestc++.a"
683	}
684    }
685
686    # Build any shared objects needed for regression testing.
687    if { ${v3-sharedlib} == 1 } {
688	set source_files [list testsuite_shared.cc]
689	foreach f $source_files {
690	    set object_file [file rootname $f].so
691	    # Compile with "-w" so that warnings issued by the compiler
692	    # do not prevent compilation.
693	    if { [v3_target_compile $srcdir/util/$f $object_file "sharedlib" \
694	     [list "incdir=$srcdir" "additional_flags=-fno-inline -w -shared -fPIC -DPIC -std=gnu++98"]]
695		 != "" } {
696		error "could not compile $f"
697	    }
698	}
699    }
700}
701
702# Implement an target check for property PROP by invoking
703# the Tcl command ARGS and seeing if it returns true.
704
705proc check_v3_target_prop_cached { prop args } {
706    global et_cache
707
708    set target [current_target_name]
709    if {![info exists et_cache($prop,$target)]} {
710	verbose "check_v3_target_prop_cached $prop: checking $target" 2
711	if {[string is true -strict $args] || [string is false -strict $args]} {
712	    error {check_v3_target_prop_cached condition already evaluated; did you pass [...] instead of the expected {...}?}
713	} else {
714	    set code [catch {uplevel eval $args} result]
715	    if {$code != 0 && $code != 2} {
716		verbose "check_v3_target_prop_cached $prop: evaluation failed for $target" 2
717		return -code $code $result
718	    }
719	    set et_cache($prop,$target) $result
720	}
721    } else {
722	verbose "check_v3_target_prop_cached $prop $target: using cached result" 2
723    }
724
725    set value $et_cache($prop,$target)
726    verbose "check_v3_target_prop_cached $prop: returning $value for $target" 2
727    return $value
728}
729
730proc check_v3_target_fileio { } {
731    return [check_v3_target_prop_cached et_fileio {
732	global tool
733	global srcdir
734
735	# Set up, compile, and execute a C++ test program that tries to use
736	# the file functions
737	set src fileio[pid].cc
738	set exe fileio[pid].x
739	set testfile "cin_unget-1.[pid].txt"
740	v3-copy-file "$srcdir/data/cin_unget-1.txt" "$testfile"
741
742	set f [open $src "w"]
743	puts $f "#include <sys/types.h>"
744	puts $f "#include <sys/stat.h>"
745	puts $f "#include <fcntl.h>"
746	puts $f "#include <unistd.h>"
747	puts $f "#include <errno.h>"
748	puts $f "#include <string.h>"
749	puts $f "using namespace std;"
750	puts $f "int main ()"
751	puts $f "{"
752	puts $f "  int fd  = open (\"$testfile\", O_RDONLY);"
753	puts $f "  int ret = 0;"
754	puts $f "  char buf\[10\];"
755	puts $f "  if (fd == -1)"
756	puts $f "    ret = 1;"
757	puts $f "  else"
758	puts $f "  {"
759	puts $f "    if (lseek (fd, -1, SEEK_CUR) != -1 || errno != EINVAL)"
760	puts $f "      ret = 1;"
761	puts $f "    errno = 0;"
762	puts $f "    if (lseek (fd, 0, SEEK_CUR) != 0"
763	puts $f "        || read (fd, buf, 4) != 4"
764	puts $f "        || memcmp (buf, \"1234\", 4) != 0"
765	puts $f "        || lseek (fd, -2, SEEK_CUR) != 2"
766	puts $f "        || read (fd, buf, 2) != 2"
767	puts $f "        || memcmp (buf, \"34\", 2) != 0)"
768	puts $f "      ret = 1;"
769	puts $f "    close (fd);"
770	puts $f "  }"
771	puts $f "  return ret;"
772	puts $f "}"
773	close $f
774
775	set lines [v3_target_compile $src $exe executable ""]
776	file delete $src
777
778	if [string match "" $lines] {
779	    # No error message, compilation succeeded.
780	    set result [${tool}_load "./$exe" "" ""]
781	    set status [lindex $result 0]
782	    remote_file build delete $exe
783
784	    verbose "check_v3_target_fileio: status is <$status>" 2
785
786	    if { $status == "pass" } {
787		return 1
788	    }
789	} else {
790	    verbose "check_v3_target_fileio: compilation failed" 2
791	}
792	return 0
793    }]
794}
795
796# Eventually we want C90/C99 determining and switching from this.
797proc check_v3_target_c_std { } {
798    return [check_v3_target_prop_cached et_c_std {
799	global tool
800	# Set up, compile, and execute a C++ test program that tries to use
801	# C99 functionality.
802	# For math bits, could use check_effective_target_c99_math.
803	set src fileio[pid].cc
804	set exe fileio[pid].x
805
806	set f [open $src "w"]
807	puts $f "#include <tr1/cmath>"
808	puts $f "#include <cstdlib>"
809	puts $f "int main ()"
810	puts $f "{"
811	puts $f "  float f = 45.55;"
812	puts $f "  int i = std::tr1::isnan(f);"
813	puts $f "  "
814	puts $f "  using std::wctomb;"
815	puts $f "  return i;"
816	puts $f "}"
817	close $f
818
819	set lines [v3_target_compile $src $exe executable ""]
820	file delete $src
821
822	if [string match "" $lines] {
823	    # No error message, compilation succeeded.
824	    set result [${tool}_load "./$exe" "" ""]
825	    set status [lindex $result 0]
826	    remote_file build delete $exe
827
828	    verbose "check_v3_target_c_std: status is <$status>" 2
829
830	    if { $status == "pass" } {
831		return 1
832	    }
833	} else {
834	    verbose "check_v3_target_c_std: compilation failed" 2
835	}
836	return 0
837    }]
838}
839
840proc check_v3_target_sharedlib { } {
841    global v3-sharedlib
842    return ${v3-sharedlib}
843}
844
845proc check_v3_target_time { } {
846    return [check_v3_target_prop_cached et_target_time {
847	global tool
848	# Set up and compile a C++ test program that tries to use
849	# the time function
850	set src time[pid].cc
851
852	set f [open $src "w"]
853	puts $f "#include <time.h>"
854	puts $f "using namespace std;"
855	puts $f "int main ()"
856	puts $f "{"
857	puts $f "  time (0);"
858	puts $f "}"
859	close $f
860
861	set lines [v3_target_compile $src /dev/null executable ""]
862	file delete $src
863
864	if [string match "" $lines] {
865	    # No error message, compilation succeeded.
866	    verbose "check_v3_target_time: compilation succeeded" 2
867	    return 1
868	} else {
869	    verbose "check_v3_target_time: compilation failed" 2
870	    return 0
871	}
872    }]
873}
874
875proc check_v3_target_namedlocale { args } {
876    set key "et_namedlocale $args"
877    return [check_v3_target_prop_cached $key {
878	global tool
879	# Set up, compile, and execute a C++ test program that tries to use
880	# the required named locale.
881	set exe nlocale[pid].x
882	set src nlocale[pid].cc
883
884	set f [open $src "w"]
885	puts $f "#include <locale>"
886	puts $f "#include <cstdio>"
887	puts $f "#include <cstring>"
888	puts $f "using namespace std;"
889	puts $f "char *transform_locale(const char *name)"
890	puts $f "{"
891	puts $f "    char *result = new char\[50\];"
892	puts $f "    strcpy(result, name);"
893	puts $f "#if defined __FreeBSD__ || defined __DragonFly__ || defined __NetBSD__"
894	puts $f "    /* fall-through */"
895	puts $f "#else"
896	puts $f "    if (strstr(result, \"ISO8859-15\")) {"
897	puts $f "        strcat(result, \"@euro\");"
898	puts $f "    }"
899	puts $f "#endif"
900	puts $f "    return result;"
901	puts $f "}"
902	puts $f "int main (int argc, char** argv)"
903	puts $f "{"
904	puts $f "  if (argc < 2)"
905	puts $f "  {"
906	puts $f "    printf(\"locale support test not supported\\n\");"
907	puts $f "    return 1;"
908	puts $f "  }"
909	puts $f "  const char *namedloc = transform_locale(*(argv + 1));"
910	puts $f "  try"
911	puts $f "  {"
912	puts $f "    locale((const char*)namedloc);"
913	puts $f "    delete\[\] namedloc;"
914	puts $f "    return 0;"
915	puts $f "  }"
916	puts $f "  catch(...)"
917	puts $f "  {"
918	puts $f "    printf(\"locale '%s' not supported\\n\", namedloc);"
919	puts $f "    delete\[\] namedloc;"
920	puts $f "    return 1;"
921	puts $f "  }"
922	puts $f "}"
923	close $f
924
925	set lines [v3_target_compile $src $exe executable ""]
926	file delete $src
927
928	if ![string match "" $lines] {
929	  verbose "check_v3_target_namedlocale: compilation failed" 2
930	  return 0
931	}
932
933	set result [${tool}_load "./$exe" "$args" ""]
934	set status [lindex $result 0]
935
936	verbose "check_v3_target_namedlocale <$args>: status is <$status>" 2
937
938	if { $status == "pass" } {
939	    return 1
940	  }
941	return 0
942    }]
943}
944
945proc check_v3_target_debug_mode { } {
946    return [check_v3_target_prop_cached et_debug_mode {
947	global tool
948	# Set up and preprocess a C++ test program that depends
949	# on debug mode activated.
950	set src debug_mode[pid].cc
951
952	set f [open $src "w"]
953	puts $f "#ifndef _GLIBCXX_DEBUG"
954	puts $f "#  error No debug mode"
955	puts $f "#endif"
956	close $f
957
958	set lines [v3_target_compile $src /dev/null preprocess ""]
959	file delete $src
960
961	if [string match "" $lines] {
962	    # No error message, preprocessing succeeded.
963	    return 1
964	}
965	return 0
966    }]
967}
968
969proc check_v3_target_profile_mode { } {
970    return [check_v3_target_prop_cached et_profile_mode {
971	global tool
972	# Set up and preprocess a C++ test program that depends
973	# on profile mode activated.
974	set src profile_mode[pid].cc
975
976	set f [open $src "w"]
977	puts $f "#ifndef _GLIBCXX_PROFILE"
978	puts $f "#  error No profile mode"
979	puts $f "#endif"
980	close $f
981
982	set lines [v3_target_compile $src /dev/null preprocess ""]
983	file delete $src
984
985	if [string match "" $lines] {
986	    # No error message, preprocessing succeeded.
987	    return 1
988	}
989	return 0
990    }]
991}
992
993proc check_v3_target_normal_mode { } {
994    return [check_v3_target_prop_cached et_normal_mode {
995	global tool
996	# Set up and compile a C++ test program that depends
997	# on normal mode activated.
998	set src normal_mode[pid].cc
999
1000	set f [open $src "w"]
1001	puts $f "#include <bits/c++config.h>"
1002	puts $f "#if defined(_GLIBCXX_DEBUG) || \\"
1003	puts $f "    defined(_GLIBCXX_PROFILE) || \\"
1004	puts $f "    defined(_GLIBCXX_PARALLEL)"
1005	puts $f "#  error No normal mode"
1006	puts $f "#endif"
1007	close $f
1008
1009	set lines [v3_target_compile $src /dev/null preprocess ""]
1010	file delete $src
1011
1012	if [string match "" $lines] {
1013	    # No error message, compilation succeeded.
1014	    return 1
1015	}
1016	return 0
1017    }]
1018}
1019
1020proc check_v3_target_normal_namespace { } {
1021    return [check_v3_target_prop_cached et_normal_namespace {
1022	global tool
1023	# Set up and compile a C++ test program that depends
1024	# on normal std namespace.
1025	set src normal_namespace[pid].cc
1026
1027	set f [open $src "w"]
1028	puts $f "#include <bits/c++config.h>"
1029	puts $f "#if _GLIBCXX_INLINE_VERSION"
1030	puts $f "#  error No normal namespace"
1031	puts $f "#endif"
1032	close $f
1033
1034	set lines [v3_target_compile $src /dev/null preprocess ""]
1035	file delete $src
1036
1037	if [string match "" $lines] {
1038	    # No error message, compilation succeeded.
1039	    return 1
1040	}
1041	return 0
1042    }]
1043}
1044
1045proc check_v3_target_parallel_mode { } {
1046    return [check_v3_target_prop_cached et_parallel_mode {
1047	global cxxflags
1048	global v3-libgomp
1049	# If 'make check-parallel' is running the test succeeds.
1050	if { ${v3-libgomp} == 1 && [regexp "libgomp" $cxxflags] } {
1051	    return 1
1052	}
1053	return 0
1054    }]
1055}
1056
1057proc check_v3_target_cstdint { } {
1058    return [check_v3_target_prop_cached et_cstdint {
1059	global DEFAULT_CXXFLAGS
1060	global cxxflags
1061	# Set up and preprocess a C++0x test program that depends
1062	# on the C99 stdint facilities to be available.
1063	set src cstdint[pid].cc
1064
1065	set f [open $src "w"]
1066	puts $f "#include <tr1/cstdint>"
1067	puts $f "#ifndef _GLIBCXX_USE_C99_STDINT_TR1"
1068	puts $f "#  error No C99 stdint"
1069	puts $f "#endif"
1070	close $f
1071
1072	set cxxflags_saved $cxxflags
1073	set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
1074
1075	set lines [v3_target_compile $src /dev/null preprocess ""]
1076	set cxxflags $cxxflags_saved
1077	file delete $src
1078
1079	if [string match "" $lines] {
1080	    # No error message, preprocess succeeded.
1081	    return 1
1082	} else {
1083	    verbose "check_v3_target_cstdint: compilation failed" 2
1084	    return 0
1085	}
1086    }]
1087}
1088
1089proc check_v3_target_cmath { } {
1090    return [check_v3_target_prop_cached et_c99_math {
1091	global cxxflags
1092	global DEFAULT_CXXFLAGS
1093	# Set up and preprocess a C++0x test program that depends
1094	# on the C99 math facilities to be available.
1095	set src c99_math[pid].cc
1096
1097	set f [open $src "w"]
1098	puts $f "#include <tr1/cmath>"
1099	puts $f "#ifndef _GLIBCXX_USE_C99_MATH_TR1"
1100	puts $f "#  error No C99 math"
1101	puts $f "#endif"
1102	close $f
1103
1104	set cxxflags_saved $cxxflags
1105	set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
1106
1107	set lines [v3_target_compile $src /dev/null preprocess ""]
1108	set cxxflags $cxxflags_saved
1109	file delete $src
1110
1111	if [string match "" $lines] {
1112	    # No error message, preprocess succeeded.
1113	    return 1
1114	} else {
1115	    verbose "check_v3_target_c99_math: compilation failed" 2
1116	    return 0
1117	}
1118    }]
1119}
1120
1121proc check_v3_target_thread_fence { } {
1122    return [check_v3_target_prop_cached et_thread_fence {
1123	global cxxflags
1124	global DEFAULT_CXXFLAGS
1125
1126	# Set up and preprocess a C++11 test program that depends
1127	# on the thread fence to be available.
1128	set src thread_fence[pid].cc
1129
1130	set f [open $src "w"]
1131	puts $f "int main() {"
1132	puts $f "__atomic_thread_fence (__ATOMIC_SEQ_CST);"
1133	puts $f "return 0;"
1134	puts $f "}"
1135	close $f
1136
1137	set cxxflags_saved $cxxflags
1138	set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror -std=gnu++11"
1139
1140	set lines [v3_target_compile $src /dev/null executable ""]
1141	set cxxflags $cxxflags_saved
1142	file delete $src
1143
1144	if [string match "" $lines] {
1145	    # No error message, linking succeeded.
1146	    return 1
1147	} else {
1148	    verbose "check_v3_target_thread_fence: compilation failed" 2
1149	    return 0
1150	}
1151    }]
1152}
1153
1154proc check_v3_target_atomic_builtins { } {
1155    return [check_v3_target_prop_cached et_atomic_builtins {
1156	global cxxflags
1157	global DEFAULT_CXXFLAGS
1158
1159	# Set up and preprocess a C++11 test program that depends
1160	# on the atomic builtin facilities to be available.
1161	set src atomic_builtins[pid].cc
1162
1163	set f [open $src "w"]
1164	puts $f "#if __GCC_ATOMIC_BOOL_LOCK_FREE < 2"
1165	puts $f "#  error No atomic bool"
1166	puts $f "#endif"
1167	puts $f "#if __GCC_ATOMIC_INT_LOCK_FREE < 2"
1168	puts $f "#  error No atomic int"
1169	puts $f "#endif"
1170	close $f
1171
1172	set cxxflags_saved $cxxflags
1173	set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror -std=gnu++11"
1174
1175	set lines [v3_target_compile $src /dev/null preprocess ""]
1176	set cxxflags $cxxflags_saved
1177	file delete $src
1178
1179	if [string match "" $lines] {
1180	    # No error message, preprocess succeeded.
1181	    return 1
1182	} else {
1183	    verbose "check_v3_target_atomic_builtins: compilation failed" 2
1184	    return 0
1185	}
1186    }]
1187}
1188
1189proc check_v3_target_gthreads { } {
1190    return [check_v3_target_prop_cached et_gthreads {
1191	global cxxflags
1192	global DEFAULT_CXXFLAGS
1193
1194	# Set up and preprocess a C++0x test program that depends
1195	# on the gthreads facilities to be available.
1196	set src gthreads[pid].cc
1197
1198	set f [open $src "w"]
1199	puts $f "#include <bits/c++config.h>"
1200	puts $f "#ifndef _GLIBCXX_HAS_GTHREADS"
1201	puts $f "#  error No gthread"
1202	puts $f "#endif"
1203	close $f
1204
1205	set cxxflags_saved $cxxflags
1206	set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
1207
1208	set lines [v3_target_compile $src /dev/null preprocess ""]
1209	set cxxflags $cxxflags_saved
1210	file delete $src
1211
1212	if [string match "" $lines] {
1213	    # No error message, preprocessing succeeded.
1214	    return 1
1215	} else {
1216	    verbose "check_v3_target_gthreads: compilation failed" 2
1217	    return 0
1218	}
1219    }]
1220}
1221
1222proc check_v3_target_gthreads_timed { } {
1223    return [check_v3_target_prop_cached et_gthreads_timed {
1224	global cxxflags
1225	global DEFAULT_CXXFLAGS
1226	# Set up and preprocess a C++0x test program that depends
1227	# on the gthreads timed mutex facilities to be available.
1228	set src gthreads_timed[pid].cc
1229
1230	set f [open $src "w"]
1231	puts $f "#include <bits/c++config.h>"
1232	puts $f "#ifndef _GLIBCXX_HAS_GTHREADS"
1233	puts $f "#  error No gthread"
1234	puts $f "#endif"
1235	puts $f "#if !_GTHREAD_USE_MUTEX_TIMEDLOCK"
1236	puts $f "#  error No gthread timed mutexes"
1237	puts $f "#endif"
1238	close $f
1239
1240	set cxxflags_saved $cxxflags
1241	set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
1242
1243	set lines [v3_target_compile $src /dev/null preprocess ""]
1244	set cxxflags $cxxflags_saved
1245	file delete $src
1246
1247	if [string match "" $lines] {
1248	    # No error message, preprocessing succeeded.
1249	    return 1
1250	} else {
1251	    verbose "check_v3_target_gthreads_timed: compilation failed" 2
1252	    return 0
1253	}
1254    }]
1255}
1256
1257proc check_v3_target_sleep { } {
1258    return [check_v3_target_prop_cached et_sleep {
1259	global cxxflags
1260	global DEFAULT_CXXFLAGS
1261	# Set up and preprocess a C++11 test program that depends
1262	# on the sleep facilities to be available.
1263	set src sleep[pid].cc
1264
1265	set f [open $src "w"]
1266	puts $f "#include <bits/c++config.h>"
1267	puts $f "#ifndef _GLIBCXX_USE_NANOSLEEP"
1268	puts $f "# ifndef _GLIBCXX_HAVE_SLEEP"
1269	puts $f "#  error No nanosleep or sleep"
1270	puts $f "# endif"
1271	puts $f "#endif"
1272	close $f
1273
1274	set cxxflags_saved $cxxflags
1275	set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
1276
1277	set lines [v3_target_compile $src /dev/null preprocess ""]
1278	set cxxflags $cxxflags_saved
1279	file delete $src
1280
1281	if [string match "" $lines] {
1282	    # No error message, preprocessing succeeded.
1283	    return 1
1284	} else {
1285	    verbose "check_v3_target_sleep: compilation failed" 2
1286	    return 0
1287	}
1288    }]
1289}
1290
1291proc check_v3_target_sched_yield { } {
1292    return [check_v3_target_prop_cached et_sched_yield {
1293	global cxxflags
1294	global DEFAULT_CXXFLAGS
1295
1296	# Set up and preprocess a C++0x test program that depends
1297	# on the sched_yield facility to be available.
1298	set src sched_yield[pid].cc
1299
1300	set f [open $src "w"]
1301	puts $f "#include <bits/c++config.h>"
1302	puts $f "#ifndef _GLIBCXX_USE_SCHED_YIELD"
1303	puts $f "#  error No sched yield"
1304	puts $f "#endif"
1305	close $f
1306
1307	set cxxflags_saved $cxxflags
1308	set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
1309
1310	set lines [v3_target_compile $src /dev/null preprocess ""]
1311	set cxxflags $cxxflags_saved
1312	file delete $src
1313
1314	if [string match "" $lines] {
1315	    # No error message, preprocessing succeeded.
1316	    return 1
1317	} else {
1318	    verbose "check_v3_target_sched_yield: compilation failed" 2
1319	    return 0
1320	}
1321    }]
1322}
1323
1324proc check_v3_target_string_conversions { } {
1325    return [check_v3_target_prop_cached et_string_conversions {
1326	global cxxflags
1327	global DEFAULT_CXXFLAGS
1328	# Set up and preprocess a C++0x test program that depends
1329	# on the string_conversions facilities to be available.
1330	set src string_conversions[pid].cc
1331
1332	set f [open $src "w"]
1333	puts $f "#include <bits/c++config.h>"
1334	puts $f "#if !(_GLIBCXX_USE_C99_STDIO && _GLIBCXX_USE_C99_STDLIB && _GLIBCXX_USE_C99_WCHAR) || defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)"
1335	puts $f "#  error No string conversions"
1336	puts $f "#endif"
1337	close $f
1338
1339	set cxxflags_saved $cxxflags
1340	set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
1341
1342	set lines [v3_target_compile $src /dev/null preprocess ""]
1343	set cxxflags $cxxflags_saved
1344	file delete $src
1345
1346	if [string match "" $lines] {
1347	    # No error message, preprocessing succeeded.
1348	    return 1
1349	} else {
1350	    verbose "check_v3_target_string_conversions: compilation failed" 2
1351	    return 0
1352	}
1353    }]
1354}
1355
1356proc check_v3_target_swprintf { } {
1357    return [check_v3_target_prop_cached et_swprintf {
1358	global cxxflags
1359	global DEFAULT_CXXFLAGS
1360	# Set up and preprocess a C++0x test program that depends
1361	# on a standard swprintf function to be available.
1362	set src swprintf[pid].cc
1363
1364	set f [open $src "w"]
1365	puts $f "#include <bits/c++config.h>"
1366	puts $f "#if defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)"
1367	puts $f "#  error No swprintf"
1368	puts $f "#endif"
1369	close $f
1370
1371	set cxxflags_saved $cxxflags
1372	set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
1373
1374	set lines [v3_target_compile $src /dev/null preprocess ""]
1375	set cxxflags $cxxflags_saved
1376	file delete $src
1377
1378	if [string match "" $lines] {
1379	    # No error message, preprocessing succeeded.
1380	    return 1
1381	} else {
1382	    verbose "check_v3_target_swprintf: compilation failed" 2
1383	    return 0
1384	}
1385    }]
1386}
1387
1388proc check_v3_target_binary_io { } {
1389    return [check_v3_target_prop_cached et_binary_io {
1390	global cxxflags
1391	global DEFAULT_CXXFLAGS
1392	# Set up and preprocess a C++0x test program that depends
1393	# on text and binary I/O being the same.
1394	set src binary_io[pid].cc
1395
1396	set f [open $src "w"]
1397	puts $f "#include <bits/c++config.h>"
1398	puts $f "#if defined(_GLIBCXX_HAVE_DOS_BASED_FILESYSTEM)"
1399	puts $f "#  error No binary io"
1400	puts $f "#endif"
1401	close $f
1402
1403	set cxxflags_saved $cxxflags
1404	set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
1405
1406	set lines [v3_target_compile $src /dev/null preprocess ""]
1407	set cxxflags $cxxflags_saved
1408	file delete $src
1409
1410	if [string match "" $lines] {
1411	    # No error message, preprocessing succeeded.
1412	    return 1
1413	} else {
1414	    verbose "check_v3_target_binary_io: compilation failed" 2
1415	    return 0
1416	}
1417    }]
1418}
1419
1420proc check_v3_target_nprocs { } {
1421    return [check_v3_target_prop_cached et_nprocs {
1422	global cxxflags
1423	global DEFAULT_CXXFLAGS
1424	# Set up and preprocess a C++0x test program that depends
1425	# on either get_nprocs or sysconf to be available.
1426	set src nprocs[pid].cc
1427
1428	set f [open $src "w"]
1429	puts $f "#include <bits/c++config.h>"
1430	puts $f "#if defined(_GLIBCXX_USE_GET_NPROCS)"
1431	puts $f "#elif defined(_GLIBCXX_USE_PTHREADS_NUM_PROCESSORS_NP)"
1432	puts $f "#elif defined(_GLIBCXX_USE_SYSCTL_HW_NCPU)"
1433	puts $f "#elif defined(_GLIBCXX_USE_SC_NPROCESSORS_ONLN)"
1434	puts $f "#elif defined(_GLIBCXX_USE_SC_NPROC_ONLN)"
1435	puts $f "#else"
1436	puts $f "#  error hardware_concurrency not implemented"
1437	puts $f "#endif"
1438	close $f
1439
1440	set cxxflags_saved $cxxflags
1441	set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
1442
1443	set lines [v3_target_compile $src /dev/null preprocess ""]
1444	set cxxflags $cxxflags_saved
1445	file delete $src
1446
1447	if [string match "" $lines] {
1448	    # No error message, preprocess succeeded.
1449	    return 1
1450	} else {
1451	    verbose "check_v3_target_nprocs: compilation failed" 2
1452	    return 0
1453	}
1454    }]
1455}
1456
1457proc check_v3_target_static_libstdcxx { } {
1458    return [check_v3_target_prop_cached et_static_libstdcxx {
1459	global cxxflags
1460	global DEFAULT_CXXFLAGS
1461	# Set up and link a C++0x test program that depends
1462	# on static linking
1463	set src static-maybe[pid].cc
1464
1465	set f [open $src "w"]
1466	puts $f "#include <iostream>"
1467	puts $f "int main() {"
1468	puts $f "int i(415);"
1469	puts $f "std::cout<< i << std::endl;"
1470	puts $f "return 0; }"
1471	puts $f ""
1472	close $f
1473
1474	set cxxflags_saved $cxxflags
1475	set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -static-libstdc++"
1476
1477	set lines [v3_target_compile $src /dev/null executable ""]
1478	set cxxflags $cxxflags_saved
1479	file delete $src
1480
1481	if [string match "" $lines] {
1482	    # No error message, link succeeded.
1483	    return 1
1484	} else {
1485	    verbose "check_v3_target_static_libstdcxx: compilation failed" 2
1486	    return 0
1487	}
1488    }]
1489}
1490
1491proc check_v3_target_little_endian { } {
1492    return [check_v3_target_prop_cached et_little_endian {
1493	global cxxflags
1494	global DEFAULT_CXXFLAGS
1495	set src little_endian[pid].cc
1496
1497	set f [open $src "w"]
1498	puts $f "#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__"
1499	puts $f "#  error Not little endian"
1500	puts $f "#endif"
1501	close $f
1502
1503	set cxxflags_saved $cxxflags
1504	set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
1505
1506	set lines [v3_target_compile $src /dev/null preprocess ""]
1507	set cxxflags $cxxflags_saved
1508	file delete $src
1509
1510	if [string match "" $lines] {
1511	    # No error message, preprocessing succeeded.
1512	    return 1
1513	} else {
1514	    verbose "check_v3_target_little_endian: compilation failed" 2
1515	    return 0
1516	}
1517    }]
1518}
1519
1520# Return 1 if the Filesystem TS is supported, 0 otherwise.
1521# Cache the result.
1522proc check_v3_target_filesystem_ts { } {
1523    return [check_v3_target_prop_cached et_filesystem_ts {
1524	global cxxflags
1525	global DEFAULT_CXXFLAGS
1526	# Set up and preprocess a C++ test program that depends
1527	# on the Filesystem TS feature-test macro being defined.
1528	set src filesystem_ts[pid].cc
1529
1530	set f [open $src "w"]
1531	puts $f "#include <experimental/filesystem>"
1532	puts $f "#if ! __cpp_lib_experimental_filesystem"
1533	puts $f "#  error No Filesystem TS support"
1534	puts $f "#endif"
1535	close $f
1536
1537	set cxxflags_saved $cxxflags
1538	set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -Werror"
1539
1540	set lines [v3_target_compile $src /dev/null preprocess ""]
1541	set cxxflags $cxxflags_saved
1542	file delete $src
1543
1544	if [string match "" $lines] {
1545	    # No error message, preprocessing succeeded.
1546	    return 1
1547	}
1548	return 0
1549    }]
1550}
1551
1552# Return 1 if the "cxx11" ABI is in use using the current flags, 0 otherwise.
1553proc check_effective_target_cxx11-abi { } {
1554    global cxxflags
1555
1556    # Set up and preprocess a C++ test program that depends
1557    # on the new ABI being enabled.
1558    set src cxx11_abi[pid].cc
1559
1560    set f [open $src "w"]
1561    puts $f "#include <bits/c++config.h>"
1562    puts $f "#if ! _GLIBCXX_USE_CXX11_ABI"
1563    puts $f "#  error old ABI in use"
1564    puts $f "#endif"
1565    close $f
1566
1567    set lines [v3_target_compile $src /dev/null preprocess ""]
1568    file delete $src
1569
1570    if [string match "" $lines] {
1571	# No error message, preprocessing succeeded.
1572	verbose "check_v3_cxx11_abi: `1'" 2
1573	return 1
1574    }
1575
1576    verbose "check_v3_cxx11_abi: `0'" 2
1577    return 0
1578}
1579
1580# Return 1 if std::random_device should be usable using the current flags, 0 otherwise.
1581proc check_effective_target_random_device { } {
1582    global cxxflags
1583
1584    # Set up and preprocess a C++ test program that depends
1585    # on std::random_device being usable.
1586    set src random_device[pid].cc
1587
1588    set f [open $src "w"]
1589    puts $f "#include <bits/c++config.h>"
1590    puts $f "#if ! _GLIBCXX_USE_RANDOM_TR1"
1591    puts $f "#  error No working std::random_device available"
1592    puts $f "#endif"
1593    close $f
1594
1595    set lines [v3_target_compile $src /dev/null preprocess ""]
1596    file delete $src
1597
1598    if [string match "" $lines] {
1599	# No error message, preprocessing succeeded.
1600	verbose "check_v3_random_device: `1'" 2
1601	return 1
1602    }
1603
1604    verbose "check_v3_random_device: `0'" 2
1605    return 0
1606}
1607
1608# Return 1 if tbb parallel backend is available
1609proc check_effective_target_tbb-backend { } {
1610    return [check_v3_target_prop_cached et_tbb {
1611        # Set up and compile a C++ test program that depends on tbb
1612        set src tbb_backend[pid].cc
1613        set exe tbb_backend[pid].x
1614
1615        set f [open $src "w"]
1616        puts $f "#include <tbb/tbb.h>"
1617        puts $f "#if TBB_INTERFACE_VERSION < 10000"
1618        puts $f "#  error Intel(R) Threading Building Blocks 2018 is required; older versions are not supported."
1619        puts $f "#endif"
1620        puts $f "int main ()"
1621        puts $f "{"
1622        puts $f "  return 0;"
1623        puts $f "}"
1624        close $f
1625
1626        set lines [v3_target_compile $src $exe executable "additional_flags=-std=c++17 additional_flags=-ltbb
1627                                                           additional_flags=-DTBB_SUPPRESS_DEPRECATED_MESSAGES=1"]
1628        file delete $src
1629
1630        if [string match "" $lines] {
1631            # No error message, compilation succeeded.
1632            verbose "check_v3_tbb-backend: `1'" 2
1633            return 1
1634        }
1635        verbose "check_v3_tbb-backend: `0'" 2
1636        return 0
1637    }]
1638}
1639
1640set additional_prunes ""
1641
1642if { [info exists env(GCC_RUNTEST_PARALLELIZE_DIR)] \
1643     && [info procs runtest_file_p] != [list] \
1644     && [info procs gcc_parallelize_saved_runtest_file_p] == [list] } then {
1645    global gcc_runtest_parallelize_counter
1646    global gcc_runtest_parallelize_counter_minor
1647    global gcc_runtest_parallelize_enable
1648    global gcc_runtest_parallelize_dir
1649    global gcc_runtest_parallelize_last
1650
1651    set gcc_runtest_parallelize_counter 0
1652    set gcc_runtest_parallelize_counter_minor 0
1653    set gcc_runtest_parallelize_enable 1
1654    set gcc_runtest_parallelize_dir [getenv GCC_RUNTEST_PARALLELIZE_DIR]
1655    set gcc_runtest_parallelize_last 0
1656
1657    proc gcc_parallel_test_run_p { testcase } {
1658	global gcc_runtest_parallelize_counter
1659	global gcc_runtest_parallelize_counter_minor
1660	global gcc_runtest_parallelize_enable
1661	global gcc_runtest_parallelize_dir
1662	global gcc_runtest_parallelize_last
1663
1664	if { $gcc_runtest_parallelize_enable == 0 } {
1665	    return 1
1666	}
1667
1668	# Only test the filesystem every 10th iteration
1669	incr gcc_runtest_parallelize_counter_minor
1670	if { $gcc_runtest_parallelize_counter_minor == 10 } {
1671	    set gcc_runtest_parallelize_counter_minor 0
1672	}
1673	if { $gcc_runtest_parallelize_counter_minor != 1 } {
1674	    #verbose -log "gcc_parallel_test_run_p $testcase $gcc_runtest_parallelize_counter $gcc_runtest_parallelize_last"
1675	    return $gcc_runtest_parallelize_last
1676	}
1677
1678	set path $gcc_runtest_parallelize_dir/$gcc_runtest_parallelize_counter
1679
1680	if {![catch {open $path {RDWR CREAT EXCL} 0600} fd]} {
1681	    close $fd
1682	    set gcc_runtest_parallelize_last 1
1683	    #verbose -log "gcc_parallel_test_run_p $testcase $gcc_runtest_parallelize_counter 1"
1684	    incr gcc_runtest_parallelize_counter
1685	    return 1
1686	}
1687	set gcc_runtest_parallelize_last 0
1688	#verbose -log "gcc_parallel_test_run_p $testcase $gcc_runtest_parallelize_counter 0"
1689	incr gcc_runtest_parallelize_counter
1690	return 0
1691    }
1692
1693    proc gcc_parallel_test_enable { val } {
1694	global gcc_runtest_parallelize_enable
1695	set gcc_runtest_parallelize_enable $val
1696    }
1697
1698    rename runtest_file_p gcc_parallelize_saved_runtest_file_p
1699    proc runtest_file_p { runtests testcase } {
1700	if ![gcc_parallelize_saved_runtest_file_p $runtests $testcase] {
1701	    return 0
1702	}
1703	return [gcc_parallel_test_run_p $testcase]
1704    }
1705
1706} else {
1707
1708    proc gcc_parallel_test_run_p { testcase } {
1709	return 1
1710    }
1711
1712    proc gcc_parallel_test_enable { val } {
1713    }
1714
1715}
1716