diff mbox

RFA: Testsuite PATCH to add support for dlopen tests

Message ID 533EE397.9010600@redhat.com
State New
Headers show

Commit Message

Jason Merrill April 4, 2014, 4:53 p.m. UTC
richi asked for a testcase for 60731, and since we didn't already have 
support for tests using dlopen, I had to add it.  Does this approach 
make sense?

Comments

Mike Stump April 6, 2014, 4:21 p.m. UTC | #1
On Apr 4, 2014, at 9:53 AM, Jason Merrill <jason@redhat.com> wrote:
> richi asked for a testcase for 60731, and since we didn't already have support for tests using dlopen, I had to add it.  Does this approach make sense?

Seems reasonable.  I wonder if it works on solaris and darwin…  I think darwin pre 10.5 might not like dlclose, but, those are old enough that I’m not going to worry about it.
Richard Biener April 7, 2014, 10 a.m. UTC | #2
On Sun, Apr 6, 2014 at 6:21 PM, Mike Stump <mikestump@comcast.net> wrote:
> On Apr 4, 2014, at 9:53 AM, Jason Merrill <jason@redhat.com> wrote:
>> richi asked for a testcase for 60731, and since we didn't already have support for tests using dlopen, I had to add it.  Does this approach make sense?
>
> Seems reasonable.  I wonder if it works on solaris and darwin...  I think darwin pre 10.5 might not like dlclose, but, those are old enough that I'm not going to worry about it.

Works for me as well.

Thanks,
Richard.
Andreas Schwab April 8, 2014, 9:01 a.m. UTC | #3
Jason Merrill <jason@redhat.com> writes:

> richi asked for a testcase for 60731, and since we didn't already have
> support for tests using dlopen, I had to add it.  Does this approach make
> sense?

ERROR: tcl error sourcing /usr/local/gcc/gcc-20140408/gcc/testsuite/g++.dg/dg.exp.
ERROR: can't rename "dg-save-unknown": command doesn't exist
    while executing
"rename dg-save-unknown unknown"
    (procedure "saved-dg-test" line 96)
    invoked from within
"saved-dg-test /usr/local/gcc/gcc-20140408/gcc/testsuite/g++.dg/dso/dlclose1.C -std=c++98 { -pedantic-errors -Wno-long-long}"
    ("eval" body line 1)
    invoked from within
"eval saved-dg-test $args "
    (procedure "dg-test" line 11)
    invoked from within
"dg-test $test $flags ${default-extra-flags}"
    (procedure "g++-dg-runtest" line 27)
    invoked from within
"g++-dg-runtest $tests $DEFAULT_CXXFLAGS"
    (file "/usr/local/gcc/gcc-20140408/gcc/testsuite/g++.dg/dg.exp" line 60)
    invoked from within
"source /usr/local/gcc/gcc-20140408/gcc/testsuite/g++.dg/dg.exp"
    ("uplevel" body line 1)
    invoked from within
"uplevel #0 source /usr/local/gcc/gcc-20140408/gcc/testsuite/g++.dg/dg.exp"
    invoked from within
"catch "uplevel #0 source $test_file_name""

Andreas.
Paolo Carlini April 8, 2014, 9:28 a.m. UTC | #4
Hi,

On 04/08/2014 11:01 AM, Andreas Schwab wrote:
> Jason Merrill <jason@redhat.com> writes:
>
>> richi asked for a testcase for 60731, and since we didn't already have
>> support for tests using dlopen, I had to add it.  Does this approach make
>> sense?
> ERROR: tcl error sourcing /usr/local/gcc/gcc-20140408/gcc/testsuite/g++.dg/dg.exp.
> ERROR: can't rename "dg-save-unknown": command doesn't exist
>      while executing
> "rename dg-save-unknown unknown"
>      (procedure "saved-dg-test" line 96)
>      invoked from within
> "saved-dg-test /usr/local/gcc/gcc-20140408/gcc/testsuite/g++.dg/dso/dlclose1.C -std=c++98 { -pedantic-errors -Wno-long-long}"
>      ("eval" body line 1)
>      invoked from within
> "eval saved-dg-test $args"
>      (procedure "dg-test" line 11)
>      invoked from within
> "dg-test $test $flags ${default-extra-flags}"
>      (procedure "g++-dg-runtest" line 27)
>      invoked from within
> "g++-dg-runtest $tests $DEFAULT_CXXFLAGS"
>      (file "/usr/local/gcc/gcc-20140408/gcc/testsuite/g++.dg/dg.exp" line 60)
>      invoked from within
> "source /usr/local/gcc/gcc-20140408/gcc/testsuite/g++.dg/dg.exp"
>      ("uplevel" body line 1)
>      invoked from within
> "uplevel #0 source /usr/local/gcc/gcc-20140408/gcc/testsuite/g++.dg/dg.exp"
>      invoked from within
> "catch "uplevel #0 source $test_file_name""
I can confirm this.

Thanks,
Paolo.
Andreas Schwab April 8, 2014, 9:58 a.m. UTC | #5
Paolo Carlini <paolo.carlini@oracle.com> writes:

> On 04/08/2014 11:01 AM, Andreas Schwab wrote:
>> Jason Merrill <jason@redhat.com> writes:
>>
>>> richi asked for a testcase for 60731, and since we didn't already have
>>> support for tests using dlopen, I had to add it.  Does this approach make
>>> sense?
>> ERROR: tcl error sourcing /usr/local/gcc/gcc-20140408/gcc/testsuite/g++.dg/dg.exp.
>> ERROR: can't rename "dg-save-unknown": command doesn't exist
>>      while executing
>> "rename dg-save-unknown unknown"
>>      (procedure "saved-dg-test" line 96)
>>      invoked from within
>> "saved-dg-test /usr/local/gcc/gcc-20140408/gcc/testsuite/g++.dg/dso/dlclose1.C -std=c++98 { -pedantic-errors -Wno-long-long}"
>>      ("eval" body line 1)
>>      invoked from within
>> "eval saved-dg-test $args"
>>      (procedure "dg-test" line 11)
>>      invoked from within
>> "dg-test $test $flags ${default-extra-flags}"
>>      (procedure "g++-dg-runtest" line 27)
>>      invoked from within
>> "g++-dg-runtest $tests $DEFAULT_CXXFLAGS"
>>      (file "/usr/local/gcc/gcc-20140408/gcc/testsuite/g++.dg/dg.exp" line 60)
>>      invoked from within
>> "source /usr/local/gcc/gcc-20140408/gcc/testsuite/g++.dg/dg.exp"
>>      ("uplevel" body line 1)
>>      invoked from within
>> "uplevel #0 source /usr/local/gcc/gcc-20140408/gcc/testsuite/g++.dg/dg.exp"
>>      invoked from within
>> "catch "uplevel #0 source $test_file_name""
> I can confirm this.

I guess this depends on dejagnu >= 1.5, which added support for nested
calls to dg-test.

Andreas.
Paolo Carlini April 8, 2014, 10:29 a.m. UTC | #6
Hi,

On 04/08/2014 11:58 AM, Andreas Schwab wrote:
> I guess this depends on dejagnu >= 1.5, which added support for nested 
> calls to dg-test.

I see, thanks Andreas. In fact I'm using 1.4.4 here. Then, either update 
prerequisites.html or tweak the code to not rely on 1.5.x features.

Paolo.
Jason Merrill April 9, 2014, 3:29 a.m. UTC | #7
On 04/08/2014 05:58 AM, Andreas Schwab wrote:
> I guess this depends on dejagnu >= 1.5, which added support for nested
> calls to dg-test.

Hmm, the PCH tests already use nested calls to dg-test, I wonder why 
they don't break this way?

Jason
Andreas Schwab April 9, 2014, 6:57 a.m. UTC | #8
Jason Merrill <jason@redhat.com> writes:

> Hmm, the PCH tests already use nested calls to dg-test,

Do they?  I don't think so.  There are calls to dg-test in dg-flags-pch,
which is called by dg-pch, and then pch.exp runs dg-pch on each test,
but I see no other dg-test in the call chain.

Andreas.
diff mbox

Patch

commit c0a86bbbb75658fcf59ae8f08c7e4588c865346c
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Apr 4 06:15:02 2014 -0400

    	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.

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..ce8ed5d 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 srcdir 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..6f4d28a 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_LAZY); }
+    } [add_options_for_dlopen ""]]
+}
+
+proc add_options_for_dlopen { flags } {
+    return "$flags -ldl"
 }
 
 # Return 1 if the target supports clone, 0 otherwise.