From: jason Date: Fri, 14 May 2010 18:55:22 +0000 (+0000) Subject: PR c++/44127 X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=1d3f675f9a122578d8cabcd04bff9c521956450e 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159408 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a5309e17649..4a71722b293 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,6 +1,12 @@ 2010-05-14 Jason Merrill 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. * gimple.h: Declare it. * gimple.c (gimple_build_eh_filter): No ops. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index eca1aaaa92c..2066fa7f13d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,6 +1,10 @@ 2010-05-14 Jason Merrill 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 gimple_build_eh_must_not_throw. diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 86acc93d255..74449fa8233 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -214,10 +214,10 @@ do_begin_catch (void) static int dtor_nothrow (tree type) { - if (type == NULL_TREE) + if (type == NULL_TREE || type == error_mark_node) return 0; - if (!CLASS_TYPE_P (type)) + if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type)) return 1; if (CLASSTYPE_LAZY_DESTRUCTOR (type)) diff --git a/gcc/gimple.c b/gcc/gimple.c index dd691a810d2..ace53b92f87 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -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_from_thunk (call, CALL_FROM_THUNK_P (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)); return call; @@ -1753,6 +1754,9 @@ gimple_call_flags (const_gimple stmt) flags = 0; } + if (stmt->gsbase.subcode & GF_CALL_NOTHROW) + flags |= ECF_NOTHROW; + return flags; } diff --git a/gcc/gimple.h b/gcc/gimple.h index 8ecf7eb0a4e..e9d21a99c73 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -106,6 +106,7 @@ enum gf_mask { GF_CALL_RETURN_SLOT_OPT = 1 << 2, GF_CALL_TAILCALL = 1 << 3, GF_CALL_VA_ARG_PACK = 1 << 4, + GF_CALL_NOTHROW = 1 << 5, GF_OMP_PARALLEL_COMBINED = 1 << 0, /* True on an GIMPLE_OMP_RETURN statement if the return does not require @@ -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. */ static inline bool diff --git a/gcc/testsuite/g++.dg/eh/terminate1.C b/gcc/testsuite/g++.dg/eh/terminate1.C index cd60bccb48b..43cc19eafcb 100644 --- a/gcc/testsuite/g++.dg/eh/terminate1.C +++ b/gcc/testsuite/g++.dg/eh/terminate1.C @@ -7,6 +7,12 @@ // { 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 { A() { }