Commit 9bb1a81b by Jason Merrill Committed by Jason Merrill

re PR c++/44127 (G++ emits unnecessary EH code)

	PR c++/44127
gcc:
	* gimple.h (enum gf_mask): Add GF_CALL_NOTHROW.
	(gimple_call_set_nothrow): New.
	* gimple.c (gimple_build_call_from_tree): Call it.
	(gimple_call_flags): Set ECF_NOTHROW from GF_CALL_NOTHROW.
gcc/cp:
	* except.c (dtor_nothrow): Return nonzero for type with
	trivial destructor.

From-SVN: r159408
parent 786f715d
2010-05-14 Jason Merrill <jason@redhat.com> 2010-05-14 Jason Merrill <jason@redhat.com>
PR c++/44127 PR c++/44127
* gimple.h (enum gf_mask): Add GF_CALL_NOTHROW.
(gimple_call_set_nothrow): New.
* gimple.c (gimple_build_call_from_tree): Call it.
(gimple_call_flags): Set ECF_NOTHROW from GF_CALL_NOTHROW.
PR c++/44127
* gimplify.c (gimplify_seq_add_stmt): No longer static. * gimplify.c (gimplify_seq_add_stmt): No longer static.
* gimple.h: Declare it. * gimple.h: Declare it.
* gimple.c (gimple_build_eh_filter): No ops. * gimple.c (gimple_build_eh_filter): No ops.
......
2010-05-14 Jason Merrill <jason@redhat.com> 2010-05-14 Jason Merrill <jason@redhat.com>
PR c++/44127 PR c++/44127
* except.c (dtor_nothrow): Return nonzero for type with
trivial destructor.
PR c++/44127
* cp-gimplify.c (gimplify_must_not_throw_expr): Use * cp-gimplify.c (gimplify_must_not_throw_expr): Use
gimple_build_eh_must_not_throw. gimple_build_eh_must_not_throw.
......
...@@ -214,10 +214,10 @@ do_begin_catch (void) ...@@ -214,10 +214,10 @@ do_begin_catch (void)
static int static int
dtor_nothrow (tree type) dtor_nothrow (tree type)
{ {
if (type == NULL_TREE) if (type == NULL_TREE || type == error_mark_node)
return 0; return 0;
if (!CLASS_TYPE_P (type)) if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
return 1; return 1;
if (CLASSTYPE_LAZY_DESTRUCTOR (type)) if (CLASSTYPE_LAZY_DESTRUCTOR (type))
......
...@@ -297,6 +297,7 @@ gimple_build_call_from_tree (tree t) ...@@ -297,6 +297,7 @@ gimple_build_call_from_tree (tree t)
gimple_call_set_return_slot_opt (call, CALL_EXPR_RETURN_SLOT_OPT (t)); gimple_call_set_return_slot_opt (call, CALL_EXPR_RETURN_SLOT_OPT (t));
gimple_call_set_from_thunk (call, CALL_FROM_THUNK_P (t)); gimple_call_set_from_thunk (call, CALL_FROM_THUNK_P (t));
gimple_call_set_va_arg_pack (call, CALL_EXPR_VA_ARG_PACK (t)); gimple_call_set_va_arg_pack (call, CALL_EXPR_VA_ARG_PACK (t));
gimple_call_set_nothrow (call, TREE_NOTHROW (t));
gimple_set_no_warning (call, TREE_NO_WARNING (t)); gimple_set_no_warning (call, TREE_NO_WARNING (t));
return call; return call;
...@@ -1753,6 +1754,9 @@ gimple_call_flags (const_gimple stmt) ...@@ -1753,6 +1754,9 @@ gimple_call_flags (const_gimple stmt)
flags = 0; flags = 0;
} }
if (stmt->gsbase.subcode & GF_CALL_NOTHROW)
flags |= ECF_NOTHROW;
return flags; return flags;
} }
......
...@@ -106,6 +106,7 @@ enum gf_mask { ...@@ -106,6 +106,7 @@ enum gf_mask {
GF_CALL_RETURN_SLOT_OPT = 1 << 2, GF_CALL_RETURN_SLOT_OPT = 1 << 2,
GF_CALL_TAILCALL = 1 << 3, GF_CALL_TAILCALL = 1 << 3,
GF_CALL_VA_ARG_PACK = 1 << 4, GF_CALL_VA_ARG_PACK = 1 << 4,
GF_CALL_NOTHROW = 1 << 5,
GF_OMP_PARALLEL_COMBINED = 1 << 0, GF_OMP_PARALLEL_COMBINED = 1 << 0,
/* True on an GIMPLE_OMP_RETURN statement if the return does not require /* True on an GIMPLE_OMP_RETURN statement if the return does not require
...@@ -2213,6 +2214,19 @@ gimple_call_noreturn_p (gimple s) ...@@ -2213,6 +2214,19 @@ gimple_call_noreturn_p (gimple s)
} }
/* If NOTHROW_P is true, GIMPLE_CALL S is a call that is known to not throw
even if the called function can throw in other cases. */
static inline void
gimple_call_set_nothrow (gimple s, bool nothrow_p)
{
GIMPLE_CHECK (s, GIMPLE_CALL);
if (nothrow_p)
s->gsbase.subcode |= GF_CALL_NOTHROW;
else
s->gsbase.subcode &= ~GF_CALL_NOTHROW;
}
/* Return true if S is a nothrow call. */ /* Return true if S is a nothrow call. */
static inline bool static inline bool
......
...@@ -7,6 +7,12 @@ ...@@ -7,6 +7,12 @@
// { dg-final { scan-assembler-not "_ZSt9terminatev" } } // { dg-final { scan-assembler-not "_ZSt9terminatev" } }
// Also there should only be two EH call sites: #0 for throw A() and #1 for
// _Unwind_Resume. We don't want call site info for __cxa_end_catch, since
// ~A is trivial.
// { dg-final { scan-assembler-not "LEHB2" } }
struct A struct A
{ {
A() { } A() { }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment