diff options
-rw-r--r-- | ld/testsuite/ld.cdtest/cdtest-foo.cc | 89 | ||||
-rw-r--r-- | ld/testsuite/ld.cdtest/cdtest-foo.h | 24 | ||||
-rw-r--r-- | ld/testsuite/ld.cdtest/cdtest-func.cc | 17 | ||||
-rw-r--r-- | ld/testsuite/ld.cdtest/cdtest-main.cc | 40 | ||||
-rw-r--r-- | ld/testsuite/ld.cdtest/cdtest.dat | 15 | ||||
-rw-r--r-- | ld/testsuite/ld.cdtest/cdtest.exp | 82 | ||||
-rw-r--r-- | ld/testsuite/lib/ld.exp | 148 |
7 files changed, 400 insertions, 15 deletions
diff --git a/ld/testsuite/ld.cdtest/cdtest-foo.cc b/ld/testsuite/ld.cdtest/cdtest-foo.cc new file mode 100644 index 0000000..f29930f --- /dev/null +++ b/ld/testsuite/ld.cdtest/cdtest-foo.cc @@ -0,0 +1,89 @@ +// Class Foo +//#pragma implementation + + +// We don't use header files, since we only want to see, whether the +// compiler is installed properly. +// +#if (__GNUG__ == 2) +typedef __SIZE_TYPE__ size_t; +#else +typedef unsigned int size_t; +#endif + +extern "C" { + char *strncpy (char* dest, const char* dest, size_t len); + int printf (const char*, ...); +}; + +#include "cdtest-foo.h" + +int Foo::foos = 0; + +void Foo::init_foo () +{ + printf ("BROKENLY calling Foo::init_foo from __init_start; size_of(Foo) = %d\n", sizeof(Foo)); + foos = FOOLISH_NUMBER; +} + + +Foo::Foo () +{ + i = ++foos; + strncpy (message, "default-foo", len); +#ifdef WITH_ADDR + printf ("Constructing Foo(%d) \"default-foo\" at %08x\n", i, this); +#else + printf ("Constructing Foo(%d) \"default-foo\"\n", i); +#endif +} + +Foo::Foo (char* msg) +{ + i = ++foos; + strncpy( message, msg, len); +#ifdef WITH_ADDR + printf ( "Constructing Foo(%d) \"%s\" at %08x\n", i, message, this); +#else + printf ( "Constructing Foo(%d) \"%s\"\n", i, message); +#endif +} + + +Foo::Foo (const Foo& foo) +{ + i = ++foos; +#ifdef WITH_ADDR + printf ("Initializing Foo(%d) \"%s\" at %08x with Foo(%d) %08x\n", + i, foo.message, this, foo.i, &foo); +#else + printf ("Initializing Foo(%d) \"%s\" with Foo(%d)\n",i, foo.message, foo.i); +#endif + for ( int k = 0; k < FOO_MSG_LEN; k++) message[k] = foo.message[k]; +} + + +Foo& Foo::operator= (const Foo& foo) +{ +#ifdef WITH_ADDR + printf ("Copying Foo(%d) \"%s\" at %08x to Foo(%d) %08x\n", + foo.i, foo.message, &foo, i, this); +#else + printf ("Copying Foo(%d) \"%s\" to Foo(%d)\n", foo.i, foo.message, i); +#endif + for ( int k = 0; k < FOO_MSG_LEN; k++) message[k] = foo.message[k]; + return *this; +} + + +Foo::~Foo () +{ + foos--; +#ifdef WITH_ADDR + printf ("Destructing Foo(%d) \"%s\" at %08x (remaining foos: %d)\n", + i, message, this, foos); +#else + printf ("Destructing Foo(%d) \"%s\" (remaining foos: %d)\n", + i, message, foos); +#endif +} diff --git a/ld/testsuite/ld.cdtest/cdtest-foo.h b/ld/testsuite/ld.cdtest/cdtest-foo.h new file mode 100644 index 0000000..0ba2d37 --- /dev/null +++ b/ld/testsuite/ld.cdtest/cdtest-foo.h @@ -0,0 +1,24 @@ +// Class Foo + +#pragma interface + +#define FOOLISH_NUMBER -4711 + +#ifndef FOO_MSG_LEN +#define FOO_MSG_LEN 80 +#endif + +class Foo { + static int foos; + int i; + const len = FOO_MSG_LEN; + char message[len]; +public: + static void init_foo (); + static int nb_foos() { return foos; } + Foo(); + Foo( char* message); + Foo(const Foo&); + Foo & operator= (const Foo&); + ~Foo (); +}; diff --git a/ld/testsuite/ld.cdtest/cdtest-func.cc b/ld/testsuite/ld.cdtest/cdtest-func.cc new file mode 100644 index 0000000..79000e3 --- /dev/null +++ b/ld/testsuite/ld.cdtest/cdtest-func.cc @@ -0,0 +1,17 @@ +// test program for Class Foo + +#include "cdtest-foo.h" + +static Foo static_foo( "static_foo"); + +Foo f() +{ + Foo x; + return x; +} + +void g() +{ + Foo other_foo1 = Foo( "other_foo1"), other_foo2 = Foo( "other_foo2"); + other_foo2 = other_foo1; +} diff --git a/ld/testsuite/ld.cdtest/cdtest-main.cc b/ld/testsuite/ld.cdtest/cdtest-main.cc new file mode 100644 index 0000000..4b99b5c --- /dev/null +++ b/ld/testsuite/ld.cdtest/cdtest-main.cc @@ -0,0 +1,40 @@ +// main program for Class Foo + +extern "C" { +// Some <assert.h> implementations (e.g. SUNOS 4.1) are broken, +// in that they require <stdio.h>. But, if gcc/g++ is installed +// correctly, you should get gcc's assert.h. +// If the compile fails, it means the wrong include files are in use! +#include <assert.h> +}; +#include "cdtest-foo.h" + +extern "C" void __init_start(); + +extern Foo f(void); +extern void g(void); + +/* This function should *not* be called by the environment. There is + no way in C++ to ``run something after the initializers but before main()''. + The library that depends on this (NIHCL) is broken. -- John Gilmore + We leave this here to test that future changes to the compiler + do not re-introduce this losing ``feature''. */ +void +__init_start() +{ + Foo::init_foo(); +} + +static Foo static_foo( "static_foo"); + +main() +{ + assert (Foo::nb_foos() == 2); + Foo automatic_foo( "automatic_foo"); + Foo bla_foo = f(); + assert (Foo::nb_foos() == 4); + g(); + assert (Foo::nb_foos() == 4); + // `automatic_foo' and `bla_foo' are destructed here +} + diff --git a/ld/testsuite/ld.cdtest/cdtest.dat b/ld/testsuite/ld.cdtest/cdtest.dat new file mode 100644 index 0000000..39be0db --- /dev/null +++ b/ld/testsuite/ld.cdtest/cdtest.dat @@ -0,0 +1,15 @@ +Constructing Foo(1) "static_foo" +Constructing Foo(2) "static_foo" +Constructing Foo(3) "automatic_foo" +Constructing Foo(4) "default-foo" +Initializing Foo(5) "default-foo" with Foo(4) +Destructing Foo(4) "default-foo" (remaining foos: 4) +Constructing Foo(5) "other_foo1" +Constructing Foo(6) "other_foo2" +Copying Foo(5) "other_foo1" to Foo(6) +Destructing Foo(6) "other_foo1" (remaining foos: 5) +Destructing Foo(5) "other_foo1" (remaining foos: 4) +Destructing Foo(5) "default-foo" (remaining foos: 3) +Destructing Foo(3) "automatic_foo" (remaining foos: 2) +Destructing Foo(2) "static_foo" (remaining foos: 1) +Destructing Foo(1) "static_foo" (remaining foos: 0) diff --git a/ld/testsuite/ld.cdtest/cdtest.exp b/ld/testsuite/ld.cdtest/cdtest.exp new file mode 100644 index 0000000..b6535c4 --- /dev/null +++ b/ld/testsuite/ld.cdtest/cdtest.exp @@ -0,0 +1,82 @@ +# +# Expect script for LD cdtest Tests +# Copyright (C) 1993 Free Software Foundation +# +# This file 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ +# +# $Id$ +# +# Written by Jeffrey Wheat (cassidy@cygnus.com) +# + +if $tracelevel then { + strace $tracelevel +} + +set tmpdir /tmp +set ld $objdir/ld.new + +set objects "$tmpdir/cdtest-main.o $tmpdir/cdtest-func.o $tmpdir/cdtest-foo.o" + +# compile the dependant objects + +verbose "### Compiling dependant objects\n" + +ld_compile $CXX $srcdir/$subdir/cdtest-foo.cc $tmpdir/cdtest-foo.o +ld_compile $CXX $srcdir/$subdir/cdtest-func.cc $tmpdir/cdtest-func.o +ld_compile $CXX $srcdir/$subdir/cdtest-main.cc $tmpdir/cdtest-main.o + +# +# main test loop +# +foreach test [glob -nocomplain $srcdir/$subdir/*.dat] { + global target + global status + global result + + set target "$srcdir/$subdir/[file tail [file rootname $test]]" + set tmptarget "$tmpdir/[file tail [file rootname $test]]" + + verbose "### Running test $target\n" + + # link the target with objects and libraries + ld_link $ld $tmptarget $objects + + # load (execute) the target + if ![file exists $tmptarget] then { + unresolved "$tmptarget doesn't exist." $result + } else { + catch "exec $tmptarget > $tmptarget.out" exec_output + + # diff the expected and actual outputs + if [file exists $tmptarget.out] then { + catch "simple_diff $target.dat $tmptarget.out" status + } else { + fail "$tmptarget.out doesn't exist. error was $status" + } + } + # remove generated targets + verbose "Exec exec rm -f $tmptarget.o $tmptarget.out" + catch "exec rm -f $tmptarget.o $tmptarget.out" result + verbose "Exec exec rm -f $tmptarget.grt $tmptarget" + catch "exec rm -f $tmptarget.grt $tmptarget" result +} + +# remove dependant objects +verbose "Exec rm -f $objects" +catch "exec rm -f $objects" result +ld_exit + + diff --git a/ld/testsuite/lib/ld.exp b/ld/testsuite/lib/ld.exp index 68a2668..f4340d0 100644 --- a/ld/testsuite/lib/ld.exp +++ b/ld/testsuite/lib/ld.exp @@ -7,7 +7,7 @@ proc default_ld_version { ld } { error "$ld does not exist" exit 1 } - + set tmp [exec $ld --version] regexp "version.*$" $tmp version @@ -17,32 +17,150 @@ proc default_ld_version { ld } { } # -# default_ld_start -# link a program using ld +# default_ld_relocate +# link an object using relocation # -proc default_ld_start { ld target } { +proc default_ld_relocate { ld target objects } { + + global HOSTING_EMU + + if { [file exists $ld] == 0 } then { + error "$ld does not exist" + exit 1 + } + + send_log "### EXEC \"$ld $HOSTING_EMU -o $target -r $objects\"\n" + verbose "### EXEC \"$ld $HOSTING_EMU -o $target -r $objects\"" + + catch "exec $ld $HOSTING_EMU -o $target -r $objects" exec_output + if ![string match "" $exec_output] then { + send_log "$exec_output\n" + verbose "$exec_output" + } +} - global OFILES + +# +# default_ld_link +# link a program using ld +# +proc default_ld_link { ld target objects } { + global BFDLIB global LIBIBERTY global HOSTING_EMU global HOSTING_CRT0 global HOSTING_LIBS - - set objects "$HOSTING_CRT0 $OFILES" - set library "$BFDLIB $LIBIBERTY $HOSTING_LIBS" - + + set objs "$HOSTING_CRT0 $objects" + set libs "$BFDLIB $LIBIBERTY $HOSTING_LIBS" + if { [file exists $ld] == 0 } then { error "$ld does not exist" exit 1 } + + send_log "### EXEC \"$ld $HOSTING_EMU -o $target $objs $libs\"\n" + verbose "### EXEC \"$ld $HOSTING_EMU -o $target $objs $libs\"" + + catch "exec $ld $HOSTING_EMU -o $target $objs $libs" exec_output + if ![string match "" $exec_output] then { + send_log "$exec_output\n" + verbose "$exec_output" + } +} + +# +# default_ld_compile +# compile an object using cc +# +proc default_ld_compile { cc source object } { + global CFLAGS + global srcdir + global subdir + + if {[which $cc] == 0} then { + error "$cc does not exist" + exit 1 + } + + send_log "$cc $CFLAGS -I$srcdir/$subdir -c $source -o $object\n" + verbose "### EXEC \"$cc $CFLAGS -I$srcdir/$subdir -c $source -o $object\"" + + catch "exec $cc $CFLAGS -I$srcdir/$subdir -c $source -o $object" exec_output + if ![string match "" $exec_output] then { + send_log "$exec_output\n" + verbose "$exec_output" + } +} - send_log "### EXEC \"$ld $HOSTING_EMU -o $target $objects $library\"\n" - verbose "### EXEC \"$ld $HOSTING_EMU -o $target $objects $library\"" 1 +# +# simple_diff +# compares two files line-by-line +# returns differences if exist +# returns null if file(s) cannot be opened +# +proc simple_diff { file_1 file_2 } { + global target + + set eof -1 + set differences 0 - catch "exec $ld $HOSTING_EMU -o $target $objects $library" ld_output - if ![string match "" $ld_output] then { - send_log "$ld_output\n" - verbose "$ld_output" 1 + if [file exists $file_1] then { + set file_a [open $file_1 r] + } else { + warning "$file_1 doesn't exist" + return + } + + if [file exists $file_2] then { + set file_b [open $file_2 r] + } else { + fail "$file_2 doesn't exist" + return + } + + verbose "### Diff'ing: $file_1 $file_2\n" 2 + + while { [gets $file_a line] != $eof } { + if [regexp "^#.*$" $line] then { + continue + } else { + lappend list_a $line + } + } + close $file_a + + while { [gets $file_b line] != $eof } { + if [regexp "^#.*$" $line] then { + continue + } else { + lappend list_b $line + } + } + close $file_b + + for { set i 0 } { $i < [llength $list_a] } { incr i } { + set line_a [lindex $list_a $i] + set line_b [lindex $list_b $i] + + verbose "\t$file_1: $i: $line_a\n" 3 + verbose "\t$file_2: $i: $line_b\n" 3 + if [string compare $line_a $line_b] then { + fail "Test: $target" + set differences 1 + + verbose "\t$file_1: $i: $line_a\n" 1 + verbose "\t$file_2: $i: $line_b\n" 1 + + send_log "\t$file_1: $i: $line_a\n" + send_log "\t$file_2: $i: $line_b\n" + } + } + + if $differences<1 then { + pass "Test: $target" } } + + |