OSDN Git Service

gcc/cp:
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 13 May 2001 01:28:18 +0000 (01:28 +0000)
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 13 May 2001 01:28:18 +0000 (01:28 +0000)
* except.c (choose_personality_routine): Export.  Add
explanatory comment.  Take an enum languages, not a boolean.
(initialize_handler_parm): Adjust to match.
* cp-tree.h: Prototype choose_personality_routine.
* lex.c (handle_pragma_java_exceptions): New function.
(init_cp_pragma): Register #pragma GCC java_exceptions.

gcc:
* extend.texi: Document #pragma GCC java_exceptions.

libjava:
* Makefile.am (libgcj_la_OBJECTS): Remove libsupc++convenience.la.
* Makefile.in: Regenerate (by hand).
* include/jvm.h: Add #pragma GCC java_exceptions at top of file.
* doc/cni.sgml: Document #pragma GCC java_exceptions.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@42027 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/except.c
gcc/cp/lex.c
gcc/extend.texi
libjava/ChangeLog
libjava/Makefile.am
libjava/Makefile.in
libjava/doc/cni.sgml
libjava/include/jvm.h

index 8ea9949..3f91ca1 100644 (file)
@@ -1,3 +1,7 @@
+2001-05-12  Zack Weinberg  <zackw@stanford.edu>
+
+       * extend.texi: Document #pragma GCC java_exceptions.
+
 2001-05-12  Neil Booth  <neil@cat.daikokuya.demon.co.uk>
 
        * c-parse.in (bison parser, init_reswords): Remove uses of
index 6c9408a..67f50d0 100644 (file)
@@ -1,3 +1,12 @@
+2001-05-12  Zack Weinberg  <zackw@stanford.edu>
+
+       * except.c (choose_personality_routine): Export.  Add
+       explanatory comment.  Take an enum languages, not a boolean.
+       (initialize_handler_parm): Adjust to match.
+       * cp-tree.h: Prototype choose_personality_routine.
+       * lex.c (handle_pragma_java_exceptions): New function.
+       (init_cp_pragma): Register #pragma GCC java_exceptions.
+
 2001-05-12  Neil Booth  <neil@cat.daikokuya.demon.co.uk>
 
        * method.c (build_mangled_C99_name): Remove unused prototype.
index d313fcd..1735042 100644 (file)
@@ -4018,6 +4018,7 @@ extern tree build_throw                           PARAMS ((tree));
 extern void mark_all_runtime_matches            PARAMS ((void));
 extern int nothrow_libfn_p                     PARAMS ((tree));
 extern void check_handlers                     PARAMS ((tree));
+extern void choose_personality_routine         PARAMS ((enum languages));
 
 /* in expr.c */
 extern void init_cplus_expand                  PARAMS ((void));
index aa372c8..e4f04e8 100644 (file)
@@ -43,7 +43,6 @@ static int dtor_nothrow PARAMS ((tree));
 static tree do_end_catch PARAMS ((tree));
 static void push_eh_cleanup PARAMS ((tree));
 static bool decl_is_java_type PARAMS ((tree decl, int err));
-static void choose_personality_routine PARAMS ((bool));
 static void initialize_handler_parm PARAMS ((tree, tree));
 static tree do_allocate_exception PARAMS ((tree));
 static int complete_ptr_ref_or_void_ptr_p PARAMS ((tree, tree));
@@ -259,9 +258,15 @@ decl_is_java_type (decl, err)
   return r;
 }
 
-static void
-choose_personality_routine (is_java)
-     bool is_java;
+/* Select the personality routine to be used for exception handling,
+   or issue an error if we need two different ones in the same
+   translation unit.
+   ??? At present eh_personality_libfunc is set to
+   __gxx_personality_(sj|v)0 in init_exception_processing - should it
+   be done here instead?  */
+void
+choose_personality_routine (lang)
+     enum languages lang;
 {
   static enum {
     chose_none,
@@ -272,28 +277,44 @@ choose_personality_routine (is_java)
 
   switch (state)
     {
-    case chose_none:
-      /* We defaulted to C++ in init_exception_processing.
-        Reconfigure for Java if we changed our minds.  */
-      if (is_java)
-       eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
-                                                  ? "__gcj_personality_sj0"
-                                                  : "__gcj_personality_v0");
-      state = (is_java ? chose_java : chose_cpp);
-      break;
+    case gave_error:
+      return;
 
     case chose_cpp:
+      if (lang != lang_cplusplus)
+       goto give_error;
+      return;
+
     case chose_java:
-      if (state != (is_java ? chose_java : chose_cpp))
-       {
-         error ("mixing C++ and Java catches in a single translation unit");
-         state = gave_error;
-       }
+      if (lang != lang_java)
+       goto give_error;
+      return;
+
+    case chose_none:
+      ; /* proceed to language selection */
+    }
+
+  switch (lang)
+    {
+    case lang_cplusplus:
+      state = chose_cpp;
       break;
 
-    case gave_error:
+    case lang_java:
+      state = chose_java;
+      eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
+                                                ? "__gcj_personality_sj0"
+                                                : "__gcj_personality_v0");
       break;
+
+    default:
+      abort ();
     }
+  return;
+
+ give_error:
+  error ("mixing C++ and Java catches in a single translation unit");
+  state = gave_error;
 }
 
 /* Initialize the catch parameter DECL.  */
@@ -318,7 +339,8 @@ initialize_handler_parm (decl, exp)
       && TREE_CODE (init_type) != REFERENCE_TYPE)
     init_type = build_reference_type (init_type);
 
-  choose_personality_routine (decl_is_java_type (init_type, 0));
+  choose_personality_routine (decl_is_java_type (init_type, 0)
+                             ? lang_java : lang_cplusplus);
 
   /* Since pointers are passed by value, initialize a reference to
      pointer catch parm with the address of the temporary.  */
index f005482..ac4c854 100644 (file)
@@ -61,6 +61,7 @@ static void handle_pragma_vtable PARAMS ((cpp_reader *));
 static void handle_pragma_unit PARAMS ((cpp_reader *));
 static void handle_pragma_interface PARAMS ((cpp_reader *));
 static void handle_pragma_implementation PARAMS ((cpp_reader *));
+static void handle_pragma_java_exceptions PARAMS ((cpp_reader *));
 static void cxx_init PARAMS ((void));
 static void cxx_finish PARAMS ((void));
 static void cxx_init_options PARAMS ((void));
@@ -687,6 +688,8 @@ init_cp_pragma ()
   cpp_register_pragma (parse_in, "GCC", "interface", handle_pragma_interface);
   cpp_register_pragma (parse_in, "GCC", "implementation",
                       handle_pragma_implementation);
+  cpp_register_pragma (parse_in, "GCC", "java_exceptions",
+                      handle_pragma_java_exceptions);
 }
 
 const char *
@@ -1181,6 +1184,18 @@ handle_pragma_implementation (dfile)
     }
 }
 
+/* Indicate that this file uses Java-personality exception handling.  */
+static void
+handle_pragma_java_exceptions (dfile)
+     cpp_reader *dfile ATTRIBUTE_UNUSED;
+{
+  tree x;
+  if (c_lex (&x) != CPP_EOF)
+    warning ("junk at end of #pragma GCC java_exceptions");
+
+  choose_personality_routine (lang_java);
+}
+
 void
 do_pending_lang_change ()
 {
index 5c52fcb..6b08843 100644 (file)
@@ -3811,6 +3811,7 @@ Predefined Macros,cpp.info,The C Preprocessor}).
 * Bound member functions:: You can extract a function pointer to the
                         method denoted by a @samp{->*} or @samp{.*} expression.
 * C++ Attributes::      Variable, function, and type attributes for C++ only.
+* Java Exceptions::     Tweaking exception handling to work with Java.
 * Deprecated Features:: Things might disappear from g++.
 * Backwards Compatibility:: Compatibilities with earlier definitions of C++.
 @end menu
@@ -4380,6 +4381,41 @@ interface table mechanism, instead of regular virtual table dispatch.
 
 @end table
 
+@node Java Exceptions
+@section Java Exceptions
+
+The Java language uses a slightly different exception handling model
+from C++.  Normally, GNU C++ will automatically detect when you are
+writing C++ code that uses Java exceptions, and handle them
+appropriately.  However, if C++ code only needs to execute destructors
+when Java exceptions are thrown through it, GCC will guess incorrectly.
+Sample problematic code:
+
+@example
+  struct S @{ ~S(); @};
+  extern void bar();    // is implemented in Java and may throw exceptions
+  void foo()
+  @{
+    S s;
+    bar();
+  @}
+@end example
+
+@noindent
+The usual effect of an incorrect guess is a link failure, complaining of
+a missing routine called @samp{__gxx_personality_v0}.
+
+You can inform the compiler that Java exceptions are to be used in a
+translation unit, irrespective of what it might think, by writing
+@samp{@w{#pragma GCC java_exceptions}} at the head of the file.  This
+@samp{#pragma} must appear before any functions that throw or catch
+exceptions, or run destructors when exceptions are thrown through them.
+
+You cannot mix Java and C++ exceptions in the same translation unit.  It
+is believed to be safe to throw a C++ exception from one file through
+another file compiled for the for the Java exception model, or vice
+versa, but there may be bugs in this area.
+
 @node Deprecated Features
 @section Deprecated Features
 
index 379a43b..56784e0 100644 (file)
@@ -1,3 +1,10 @@
+2001-05-12  Zack Weinberg  <zackw@stanford.edu>
+
+       * Makefile.am (libgcj_la_OBJECTS): Remove libsupc++convenience.la.
+       * Makefile.in: Regenerate (by hand).
+       * include/jvm.h: Add #pragma GCC java_exceptions at top of file.
+       * doc/cni.sgml: Document #pragma GCC java_exceptions.
+
 2001-05-11  Richard Henderson  <rth@redhat.com>
 
        * configure.in (ia64-*): Don't set SYSDEP_SOURCES.
index d5644a1..3760b32 100644 (file)
@@ -260,7 +260,6 @@ libgcj.la: $(libgcj_la_OBJECTS) $(libgcj_la_DEPENDENCIES)
        @echo $(libgcj_la_OBJECTS) > libgcj.objectlist;
        @echo $(libgcj_la_LIBADD) >> libgcj.objectlist;
        $(libgcj_la_LINK) -objectlist libgcj.objectlist \
-       ../libstdc++-v3/libsupc++/libsupc++convenience.la \
        ../libffi/libfficonvenience.la \
        -rpath $(toolexeclibdir) $(libgcj_la_LDFLAGS) $(LIBS)
 
index d4435b6..2002567 100644 (file)
@@ -2466,7 +2466,6 @@ libgcj.la: $(libgcj_la_OBJECTS) $(libgcj_la_DEPENDENCIES)
        @echo $(libgcj_la_OBJECTS) > libgcj.objectlist;
        @echo $(libgcj_la_LIBADD) >> libgcj.objectlist;
        $(libgcj_la_LINK) -objectlist libgcj.objectlist \
-       ../libstdc++-v3/libsupc++/libsupc++convenience.la \
        ../libffi/libfficonvenience.la \
        -rpath $(toolexeclibdir) $(libgcj_la_LDFLAGS) $(LIBS)
 
index 0c82ca6..495e3e9 100644 (file)
@@ -779,6 +779,31 @@ if (i >= count)
    throw new java::lang::IndexOutOfBoundsException();
 </programlisting>
 </para>
+<para>
+Normally, GNU C++ will automatically detect when you are writing C++
+code that uses Java exceptions, and handle them appropriately.
+However, if C++ code only needs to execute destructors when Java
+exceptions are thrown through it, GCC will guess incorrectly.  Sample
+problematic code:
+<programlisting>
+  struct S { ~S(); };
+  extern void bar();    // is implemented in Java and may throw exceptions
+  void foo()
+  {
+    S s;
+    bar();
+  }
+</programlisting>
+The usual effect of an incorrect guess is a link failure, complaining of
+a missing routine called <literal>__gxx_personality_v0</literal>.
+</para>
+<para>
+You can inform the compiler that Java exceptions are to be used in a
+translation unit, irrespective of what it might think, by writing
+<literal>#pragma GCC java_exceptions</literal> at the head of the
+file.  This <literal>#pragma</literal> must appear before any
+functions that throw or catch exceptions, or run destructors when
+exceptions are thrown through them.</para>
 </sect1>
 
 <sect1><title>Synchronization</title>
index 50af756..1e80fbc 100644 (file)
@@ -11,6 +11,9 @@ details.  */
 #ifndef __JAVA_JVM_H__
 #define __JAVA_JVM_H__
 
+// Force C++ compiler to use Java-style exceptions.
+#pragma GCC java_exceptions
+
 #include <gcj/javaprims.h>
 
 #include <java-assert.h>