This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[basic-improvements] try/finally support for c/c++ - more tests


Hi!

On Tue, Nov 05, 2002 at 03:19:02PM -0800, Aldy Hernandez wrote:
> As promised.  Here are the try/finally patches for C and C++.
> 
> As can be seen by the ChangeLog, the C++ bits were kindly supplied by
> Jason Merrill (thank-you beers still pending).
> 
> Jakub has some tests for try/finally mixing C and C++ exceptions.
> He'll be posting those later, right? :)

Attached.
One test for throwing from C++ through C code with __try/__finally,
one test showing what approximately could libpthread do (well, there
is still a problem if some function in the backtrace from the point of
cancellation to __libc_start_main resp. pthread_start_thread is compiled
with -fno-exceptions, _Unwind_Resume will abort. I think a callback is
needed for that (e.g. calling the stop callback with
some special arguments).

2002-11-06  Jakub Jelinek  <jakub@redhat.com>

	* Makefile.in (USER_H): Install unwind.h.
	* libgcc-std.ver (__gcc_personality_v0, __gcc_personality_sj0):
	Export @GCC_3.4.

	* lib/g++-dg.exp (g++-dg-test): Add g++-dg-aux-sources to additional
	flags.
	(dg-aux-sources): New subroutine.
	* g++.dg/ext/try-finally-1.C: New test.
	* g++.dg/ext/try-finally-1-aux.c: New auxiliary file for the test.
	* gcc.dg/try-finally-1.c: New test.

--- gcc/Makefile.in.jj	2002-10-25 14:12:50.000000000 +0200
+++ gcc/Makefile.in	2002-11-06 18:44:16.000000000 +0100
@@ -157,7 +157,7 @@ INSTALL_HEADERS_DIR = @build_install_hea
 USER_H = $(srcdir)/ginclude/stdarg.h $(srcdir)/ginclude/stddef.h \
     $(srcdir)/ginclude/varargs.h \
     $(srcdir)/ginclude/stdbool.h $(srcdir)/ginclude/iso646.h \
-    $(EXTRA_HEADERS)
+    $(srcdir)/unwind.h $(EXTRA_HEADERS)
 
 # The GCC to use for compiling libgcc.a, enquire, and crt*.o.
 # Usually the one we just built.
--- gcc/libgcc-std.ver.jj	2001-07-22 21:34:05.000000000 +0200
+++ gcc/libgcc-std.ver	2002-11-05 14:11:03.000000000 +0100
@@ -175,3 +175,7 @@ GCC_3.0 {
   _Unwind_SjLj_ForcedUnwind
   _Unwind_SjLj_Resume
 }
+GCC_3.4 {
+  __gcc_personality_v0
+  __gcc_personality_sj0
+}
--- gcc/testsuite/lib/g++-dg.exp.jj	2002-01-23 16:29:52.000000000 +0100
+++ gcc/testsuite/lib/g++-dg.exp	2002-11-05 13:57:13.000000000 +0100
@@ -23,6 +23,7 @@ load_lib scanasm.exp
 
 proc g++-dg-test { prog do_what extra_tool_flags } {
     # Set up the compiler flags, based on what we're going to do.
+    global g++-dg-aux-sources
 
     switch $do_what {
 	"preprocess" {
@@ -59,6 +60,10 @@ proc g++-dg-test { prog do_what extra_to
 	}
     }
     set options ""
+    if { ${g++-dg-aux-sources} != "" } {
+	append extra_tool_flags "${g++-dg-aux-sources}"
+	set g++-dg-aux-sources ""
+    }
     if { $extra_tool_flags != "" } {
 	lappend options "additional_flags=$extra_tool_flags"
     }
@@ -82,3 +87,22 @@ proc g++-dg-prune { system text } {
 
     return $text
 }
+
+
+#
+# Add additional sources to compile together with the main source file
+#
+
+proc dg-aux-sources { args } {
+    global g++-dg-aux-sources
+    upvar prog myprog
+
+    foreach arg [lrange $args 1 [llength $args]] {
+      set filename "[file dirname $myprog]/$arg"
+      if { [file extension $arg] == ".c" } {
+	append g++-dg-aux-sources " -xc $filename -xnone"
+      } else {
+	append g++-dg-aux-sources " $filename"
+      }
+    }
+}
--- gcc/testsuite/g++.dg/ext/try-finally-1.C.jj	2002-11-05 14:13:46.000000000 +0100
+++ gcc/testsuite/g++.dg/ext/try-finally-1.C	2002-11-05 12:47:17.000000000 +0100
@@ -0,0 +1,31 @@
+// { dg-do run }
+// { dg-options "-O2 -fexceptions" }
+// { dg-aux-sources try-finally-1-aux.c }
+
+extern int caught;
+extern "C" void test (void);
+extern "C" void do_throw (void);
+extern "C" void abort (void);
+
+void
+do_throw (void)
+{
+  caught |= 4;
+  throw 1;
+}
+
+int
+main ()
+{
+  try
+    {
+      test ();
+    }
+  catch(...)
+    {
+      caught |= 8;
+    }
+  if (caught != 15)
+    abort ();
+  return 0;
+}
--- gcc/testsuite/g++.dg/ext/try-finally-1-aux.c.jj	2002-11-05 14:13:48.000000000 +0100
+++ gcc/testsuite/g++.dg/ext/try-finally-1-aux.c	2002-11-05 12:43:30.000000000 +0100
@@ -0,0 +1,23 @@
+int caught;
+extern void do_throw (void);
+extern void abort (void);
+
+void
+test (void)
+{
+  caught |= 1;
+  __try
+    {
+      do_throw ();
+    }
+  __finally
+    {
+      finally ();
+    }
+  abort ();
+}
+
+finally()
+{
+  caught |= 2;
+}
--- gcc/testsuite/gcc.dg/try-finally-1.c.jj	2002-07-23 20:50:16.000000000 +0200
+++ gcc/testsuite/gcc.dg/try-finally-1.c	2002-11-06 18:46:39.000000000 +0100
@@ -0,0 +1,94 @@
+/* { dg-do run { target i?86-*-linux* x86_64-*-linux* ia64-*-linux* sparc*-*-linux* } } */
+/* { dg-options "-O2 -fexceptions" } */
+
+#include <unwind.h>
+
+int caught;
+
+void finally (void);
+void do_throw (void);
+extern void abort (void);
+extern void exit (int);
+
+void
+test1 (void)
+{
+  caught |= 1;
+  __try
+    {
+      do_throw ();
+      abort ();
+    }
+  __finally
+    {
+      finally ();
+    }
+  abort ();
+}
+
+void
+test2 (void)
+{
+  caught |= 2;
+  __try
+    {
+      test1 ();
+      abort ();
+    }
+  __finally
+    {
+      caught |= 4;
+    }
+  abort ();
+}
+
+void
+test3 (void)
+{
+  test2 ();
+  caught = 0;
+}
+
+void
+finally (void)
+{
+  caught |= 8;
+}
+
+void
+exception_cleanup (_Unwind_Reason_Code code,
+		   struct _Unwind_Exception *exc)
+{
+}
+
+_Unwind_Reason_Code
+stop_fn (int x, _Unwind_Action action, _Unwind_Exception_Class class,
+	 struct _Unwind_Exception *exc, struct _Unwind_Context *ctx, void *arg)
+{
+  /* This would actually check for __libc_start_main or
+     pthread_start_thread.  */
+  if ((void *) _Unwind_GetRegionStart (ctx) == (void *) test3)
+    {
+      if (caught != 15)
+	abort ();
+      exit (0);
+    }
+  return _URC_NO_REASON;
+}
+
+struct _Unwind_Exception ue;
+
+void
+do_throw (void)
+{
+  ue.exception_class = 1;
+  ue.exception_cleanup = exception_cleanup;
+  _Unwind_ForcedUnwind (&ue, stop_fn, 0);
+}
+
+int
+main (void)
+{
+  test3 ();
+  abort ();
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]