aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@gcc.gnu.org>1997-12-02 22:37:17 -0500
committerJason Merrill <jason@gcc.gnu.org>1997-12-02 22:37:17 -0500
commitde35891e2105fde8ce0f0a2e3a9f2fab01d87cce (patch)
treeb4abd2c565f65c91be1f1496f0268eb329586c7e
parent9fb82071ffbee07329eeff32ee26f8170f672123 (diff)
downloadgcc-de35891e2105fde8ce0f0a2e3a9f2fab01d87cce.zip
gcc-de35891e2105fde8ce0f0a2e3a9f2fab01d87cce.tar.gz
gcc-de35891e2105fde8ce0f0a2e3a9f2fab01d87cce.tar.bz2
[multiple changes]
Tue Dec 2 19:18:50 1997 Mike Stump <mrs@wrs.com> * class.c (prepare_fresh_vtable): Enable even more complex MI vtable names. Tue Dec 2 01:37:19 1997 Jason Merrill <jason@yorick.cygnus.com> * exception.cc (__check_eh_spec): Optimize a bit. * exception.cc (__cp_pop_exception): Lose handler arg. * except.c (do_pop_exception): Likewise. (push_eh_cleanup): Let the cleanup mechanism supply the handler. (expand_end_catch_block): Likewise. From-SVN: r16895
-rw-r--r--gcc/cp/ChangeLog14
-rw-r--r--gcc/cp/class.c33
-rw-r--r--gcc/cp/except.c25
-rw-r--r--gcc/cp/exception.cc22
4 files changed, 66 insertions, 28 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7ceb75a..a91d9e3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,17 @@
+Tue Dec 2 19:18:50 1997 Mike Stump <mrs@wrs.com>
+
+ * class.c (prepare_fresh_vtable): Enable even more complex MI
+ vtable names.
+
+Tue Dec 2 01:37:19 1997 Jason Merrill <jason@yorick.cygnus.com>
+
+ * exception.cc (__check_eh_spec): Optimize a bit.
+
+ * exception.cc (__cp_pop_exception): Lose handler arg.
+ * except.c (do_pop_exception): Likewise.
+ (push_eh_cleanup): Let the cleanup mechanism supply the handler.
+ (expand_end_catch_block): Likewise.
+
Fri Nov 28 01:58:14 1997 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (check_explicit_specialization): Complain about using a
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index d021fae..9eb6190 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -784,7 +784,8 @@ prepare_fresh_vtable (binfo, for_type)
while (1)
{
- char *buf1 = (char *) alloca (TYPE_ASSEMBLER_NAME_LENGTH (for_type) + 1 + i);
+ char *buf1 = (char *) alloca (TYPE_ASSEMBLER_NAME_LENGTH (for_type)
+ + 1 + i);
char *new_buf2;
sprintf (buf1, "%s%c%s", TYPE_ASSEMBLER_NAME_STRING (for_type), joiner,
@@ -808,8 +809,34 @@ prepare_fresh_vtable (binfo, for_type)
basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (path));
- /* We better not run out of stuff to make it unique. */
- my_friendly_assert (for_type != basetype, 369);
+ if (for_type == basetype)
+ {
+ /* If we run out of basetypes in the path, we have already
+ found created a vtable with that name before, we now
+ resort to tacking on _%d to distinguish them. */
+ int j = 2;
+ i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i + 1 + 3;
+ buf1 = (char *) alloca (i);
+ do {
+ sprintf (buf1, "%s%c%s%c%d",
+ TYPE_ASSEMBLER_NAME_STRING (basetype), joiner,
+ buf2, joiner, j);
+ buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT)
+ + strlen (buf1) + 1);
+ sprintf (buf, VTABLE_NAME_FORMAT, buf1);
+ name = get_identifier (buf);
+
+ /* If this name doesn't clash, then we can use it,
+ otherwise we add something different to the name until
+ it is unique. */
+ } while (++j <= 999 && IDENTIFIER_GLOBAL_VALUE (name));
+
+ /* Hey, they really like MI don't they? Increase the 3
+ above to 6, and the 999 to 999999. :-) */
+ my_friendly_assert (j <= 999, 369);
+
+ break;
+ }
i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i;
new_buf2 = (char *) alloca (i);
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index d72c04a..6e7c876 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -440,8 +440,7 @@ build_eh_type (exp)
if it is, it avoids destroying the object on rethrow. */
static tree
-do_pop_exception (handler)
- tree handler;
+do_pop_exception ()
{
tree fn, cleanup;
fn = get_identifier ("__cp_pop_exception");
@@ -456,9 +455,7 @@ do_pop_exception (handler)
fn = build_lang_decl
(FUNCTION_DECL, fn,
build_function_type (void_type_node, tree_cons
- (NULL_TREE, ptr_type_node, tree_cons
- (NULL_TREE, boolean_type_node,
- void_list_node))));
+ (NULL_TREE, ptr_type_node, void_list_node)));
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
@@ -471,8 +468,7 @@ do_pop_exception (handler)
/* Arrange to do a dynamically scoped cleanup upon exit from this region. */
cleanup = lookup_name (get_identifier ("__exception_info"), 0);
cleanup = build_function_call (fn, expr_tree_cons
- (NULL_TREE, cleanup, expr_tree_cons
- (NULL_TREE, handler, NULL_TREE)));
+ (NULL_TREE, cleanup, NULL_TREE));
return cleanup;
}
@@ -481,17 +477,15 @@ do_pop_exception (handler)
static void
push_eh_cleanup ()
{
- /* All cleanups must last longer than normal. */
- int yes = suspend_momentary ();
- expand_decl_cleanup_no_eh (NULL_TREE, do_pop_exception (boolean_false_node));
- resume_momentary (yes);
+ int yes;
expand_expr (build_unary_op (PREINCREMENT_EXPR, get_eh_handlers (), 1),
const0_rtx, VOIDmode, EXPAND_NORMAL);
- /* We don't destroy the exception object on rethrow, so we can't use
- the normal cleanup mechanism for it. */
- expand_eh_region_start ();
+ yes = suspend_momentary ();
+ /* All cleanups must last longer than normal. */
+ expand_decl_cleanup (NULL_TREE, do_pop_exception ());
+ resume_momentary (yes);
}
/* call this to start a catch block. Typename is the typename, and identifier
@@ -657,9 +651,6 @@ expand_end_catch_block ()
expand_end_bindings (getdecls (), kept_level_p (), 0);
poplevel (kept_level_p (), 1, 0);
- /* Matches push_eh_cleanup. */
- expand_eh_region_end (do_pop_exception (boolean_true_node));
-
/* Cleanup the EH object. */
expand_end_bindings (getdecls (), kept_level_p (), 0);
poplevel (kept_level_p (), 1, 0);
diff --git a/gcc/cp/exception.cc b/gcc/cp/exception.cc
index 9c87670..aa5a46e 100644
--- a/gcc/cp/exception.cc
+++ b/gcc/cp/exception.cc
@@ -126,17 +126,20 @@ __cp_push_exception (void *value, void *type, void (*cleanup)(void *, int))
/* Compiler hook to pop an exception that has been finalized. Used by
push_eh_cleanup(). P is the info for the exception caught by the
- current catch block, and HANDLER determines if we've been called from
- an exception handler; if so, we avoid destroying the object on rethrow. */
+ current catch block. */
extern "C" void
-__cp_pop_exception (cp_eh_info *p, bool handler)
+__cp_pop_exception (cp_eh_info *p)
{
cp_eh_info **q = &__eh_info;
--p->handlers;
- if (p->handlers > 0 || (handler && p == *q))
+ /* Don't really pop if there are still active handlers for our exception,
+ or if our exception is being rethrown (i.e. if the active exception is
+ our exception and it is uncaught). */
+ if (p->handlers != 0
+ || (p == *q && !p->caught))
return;
for (; *q; q = &((*q)->next))
@@ -198,11 +201,14 @@ __check_eh_spec (int n, const void **spec)
catch (...)
{
// __exception_info is an artificial var pushed into each catch block.
- p = __exception_info;
- for (int i = 0; i < n; ++i)
+ if (p != __exception_info)
{
- if (__throw_type_match_rtti (spec[i], p->type, p->value))
- throw;
+ p = __exception_info;
+ for (int i = 0; i < n; ++i)
+ {
+ if (__throw_type_match_rtti (spec[i], p->type, p->value))
+ throw;
+ }
}
const type_info &bad_exc = typeid (bad_exception);