diff options
author | Jason Merrill <jason@redhat.com> | 2014-04-07 09:27:45 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2014-04-07 09:27:45 -0400 |
commit | 9d7aea5fbc096600902e28e3203d67379f301f2b (patch) | |
tree | 237ccb99133c0a6b115c594981f93ed9d688628f /gcc | |
parent | da34ade5e6c93713fc9cb0b7b505afb06b01b95a (diff) | |
download | gcc-9d7aea5fbc096600902e28e3203d67379f301f2b.zip gcc-9d7aea5fbc096600902e28e3203d67379f301f2b.tar.gz gcc-9d7aea5fbc096600902e28e3203d67379f301f2b.tar.bz2 |
re PR c++/60731 (dynamic library not getting reinitialized on multiple calls to dlopen())
PR c++/60731
* lib/gcc-dg.exp (dg-build-dso): New.
(gcc-dg-test-1): Handle dg-do-what "dso".
* lib/target-supports.exp (add_options_for_dlopen): New.
(check_effective_target_dlopen): Use it.
* g++.dg/dso/dlclose1.C: New.
* g++.dg/dso/dlclose1-dso.cc: New.
From-SVN: r209187
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/dso/dlclose1-dso.cc | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/dso/dlclose1.C | 30 | ||||
-rw-r--r-- | gcc/testsuite/lib/gcc-dg.exp | 26 | ||||
-rw-r--r-- | gcc/testsuite/lib/target-supports.exp | 9 |
5 files changed, 80 insertions, 1 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 496bd44..4b25290 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2014-04-07 Jason Merrill <jason@redhat.com> + + * lib/gcc-dg.exp (dg-build-dso): New. + (gcc-dg-test-1): Handle dg-do-what "dso". + * lib/target-supports.exp (add_options_for_dlopen): New. + (check_effective_target_dlopen): Use it. + 2014-04-07 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> * gcc.target/arm/pr60657.c: Fix missing curly brace. diff --git a/gcc/testsuite/g++.dg/dso/dlclose1-dso.cc b/gcc/testsuite/g++.dg/dso/dlclose1-dso.cc new file mode 100644 index 0000000..cede483 --- /dev/null +++ b/gcc/testsuite/g++.dg/dso/dlclose1-dso.cc @@ -0,0 +1,9 @@ +// { dg-options "-fno-gnu-unique" } + +// A static variable in an inline function uses STB_GNU_UNIQUE normally. +inline int foo() { static int i; return ++i; } + +extern "C" int fn() +{ + return foo(); +} diff --git a/gcc/testsuite/g++.dg/dso/dlclose1.C b/gcc/testsuite/g++.dg/dso/dlclose1.C new file mode 100644 index 0000000..95b6fea --- /dev/null +++ b/gcc/testsuite/g++.dg/dso/dlclose1.C @@ -0,0 +1,30 @@ +// PR c++/60731 +// { dg-do run { target dlopen } } +// { dg-add-options dlopen } +// { dg-build-dso "dlclose1-dso.cc" } + +#include <dlfcn.h> +extern "C" void abort(); +extern "C" int printf (const char *, ...); + +// Open and close the DSO for each call so that statics are reinitialized. +int call() +{ + void *h = dlopen ("./dlclose1-dso.so", RTLD_NOW); + if (!h) { printf ("dlopen failed: %s\n", dlerror()); abort(); } + int (*fn)() = (int(*)())dlsym (h, "fn"); + if (!fn) { printf ("dlsym failed: %s\n", dlerror()); abort(); } + int r = fn(); + dlclose (h); + return r; +} + +int main() { + int i = call(); + int j = call(); + if (i != j) + { + printf ("mismatch: %d != %d\n", i, j); + abort(); + } +} diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp index f9d52bc..89eec95 100644 --- a/gcc/testsuite/lib/gcc-dg.exp +++ b/gcc/testsuite/lib/gcc-dg.exp @@ -144,6 +144,11 @@ proc gcc-dg-test-1 { target_compile prog do_what extra_tool_flags } { # The following line is needed for targets like the i960 where # the default output file is b.out. Sigh. } + "dso" { + set compile_type "executable" + set output_file "[file rootname [file tail $prog]].so" + set extra_tool_flags "$extra_tool_flags -fPIC -shared" + } "repo" { set compile_type "object" set output_file "[file rootname [file tail $prog]].o" @@ -181,6 +186,7 @@ proc gcc-dg-test-1 { target_compile prog do_what extra_tool_flags } { lappend options "additional_flags=$extra_tool_flags" } + verbose "$target_compile $prog $output_file $compile_type $options" 4 set comp_output [$target_compile "$prog" "$output_file" "$compile_type" $options] # Look for an internal compiler error, which sometimes masks the fact @@ -208,6 +214,26 @@ proc gcc-dg-test { prog do_what extra_tool_flags } { return [gcc-dg-test-1 gcc_target_compile $prog $do_what $extra_tool_flags] } +# Usage: { dg-build-dso "file.ext" } +# Compiles the specified file into "file.so" (treating that compilation as +# a separate test) for use by the main test, and schedules it for removal +# when the main test is complete. The DSO source file should not use "dg-do". +# This relies on a couple of local variable names in dg-test. + +proc dg-build-dso { args } { + global dg-do-what-default + upvar prog main_file + upvar dg-final-code final-code + + set file [lindex $args 1] + set dir "[file dirname $main_file]" + set dg-do-what-default dso + dg-test -keep-output $dir/$file "" "" + + set output_file "[file rootname [file tail $file]].so" + append final-code "remove-build-file $output_file" +} + proc gcc-dg-prune { system text } { global additional_prunes diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 0d2ccd5..1a5c2fa 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -746,7 +746,14 @@ proc check_effective_target_mmap {} { # Return 1 if the target supports dlopen, 0 otherwise. proc check_effective_target_dlopen {} { - return [check_function_available "dlopen"] + return [check_no_compiler_messages dlopen executable { + #include <dlfcn.h> + int main(void) { dlopen ("dummy.so", RTLD_NOW); } + } [add_options_for_dlopen ""]] +} + +proc add_options_for_dlopen { flags } { + return "$flags -ldl" } # Return 1 if the target supports clone, 0 otherwise. |