From 4bbf9b5b429eda64aca50d9c511d5281904955eb Mon Sep 17 00:00:00 2001 From: jason Date: Wed, 3 Dec 1997 03:37:17 +0000 Subject: [PATCH] Tue Dec 2 19:18:50 1997 Mike Stump * class.c (prepare_fresh_vtable): Enable even more complex MI vtable names. Tue Dec 2 01:37:19 1997 Jason Merrill * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@16895 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 14 ++++++++++++++ gcc/cp/class.c | 33 ++++++++++++++++++++++++++++++--- gcc/cp/except.c | 25 ++++++++----------------- gcc/cp/exception.cc | 22 ++++++++++++++-------- 4 files changed, 66 insertions(+), 28 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7ceb75a00d5..a91d9e30deb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +Tue Dec 2 19:18:50 1997 Mike Stump + + * class.c (prepare_fresh_vtable): Enable even more complex MI + vtable names. + +Tue Dec 2 01:37:19 1997 Jason Merrill + + * 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 * pt.c (check_explicit_specialization): Complain about using a diff --git a/gcc/cp/class.c b/gcc/cp/class.c index d021fae7dbd..9eb619094f1 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 d72c04a7e00..6e7c876467f 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 9c876700574..aa5a46e2b26 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); -- 2.11.4.GIT