+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
+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.
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));
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));
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,
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. */
&& 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. */
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));
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 *
}
}
+/* 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 ()
{
* 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
@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
+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.
@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)
@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)
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>
#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>