+2004-02-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/13944
+ * except.c (do_free_exception): Remove #if 0 wrapper.
+ (build_throw): Use it if we elide a copy into the exception object.
+
2004-03-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
* decl.c (current_binding_level): Define as an lvalue.
NULL_TREE));
}
-#if 0
-/* Call __cxa_free_exception from a cleanup. This is never invoked
- directly, but see the comment for stabilize_throw_expr. */
+/* Call __cxa_free_exception from a cleanup. */
static tree
do_free_exception (ptr)
return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
}
-#endif
/* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
Called from build_throw via walk_tree_without_duplicates. */
tree object, ptr;
tree tmp;
tree temp_expr, allocate_expr;
+ bool elided;
fn = get_identifier ("__cxa_throw");
if (IDENTIFIER_GLOBAL_VALUE (fn))
object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
object = build_indirect_ref (object, NULL);
+ elided = (TREE_CODE (exp) == TARGET_EXPR);
+
/* And initialize the exception object. */
exp = build_init (object, exp, LOOKUP_ONLYCONVERTING);
if (exp == error_mark_node)
return error_mark_node;
}
- exp = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (exp), exp);
+ if (elided)
+ exp = build (TRY_CATCH_EXPR, void_type_node, exp,
+ do_free_exception (ptr));
+ else
+ exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp);
/* Prepend the allocation. */
exp = build (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
if (temp_expr != void_zero_node)