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
This commit is contained in:
Jason Merrill 2014-04-07 09:27:45 -04:00 committed by Jason Merrill
parent da34ade5e6
commit 9d7aea5fbc
5 changed files with 80 additions and 1 deletions

View File

@ -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.

View File

@ -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();
}

View File

@ -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();
}
}

View File

@ -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

View File

@ -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.