aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/except.c4
-rw-r--r--gcc/gimple.c4
-rw-r--r--gcc/gimple.h14
-rw-r--r--gcc/testsuite/g++.dg/eh/terminate1.C6
6 files changed, 36 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a5309e1..4a71722 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,12 @@
2010-05-14 Jason Merrill <jason@redhat.com>
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 eca1aaa..2066fa7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,6 +1,10 @@
2010-05-14 Jason Merrill <jason@redhat.com>
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 86acc93..74449fa 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 dd691a8..ace53b9 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 8ecf7eb..e9d21a9 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 cd60bcc..43cc19e 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() { }