===================================================================
@@ -1163,7 +1161,10 @@ ignore_edge_for_nothrow (struct cgraph_e
enum availability avail;
cgraph_node *n = e->callee->function_or_virtual_thunk_symbol (&avail,
e->caller);
- return (avail <= AVAIL_INTERPOSABLE || TREE_NOTHROW (n->decl));
+ if (avail <= AVAIL_INTERPOSABLE || TREE_NOTHROW (n->decl))
+ return true;
+ return opt_for_fn (e->callee->decl, flag_non_call_exceptions)
+ && !e->callee->binds_to_current_def_p (e->caller);
}
/* Return true if NODE is self recursive function.
@@ -1589,14 +1595,20 @@ propagate_nothrow (void)
continue;
struct cgraph_node *y = e->callee->
- function_or_virtual_thunk_symbol (&avail,
- e->caller);
+ function_or_virtual_thunk_symbol (&avail,
+ e->caller);
/* We can use info about the callee only if we know it can
- not be interposed. */
+ not be interposed.
+ When callee is compiled with non-call exceptions we also
+ must check that the declaration is bound to current
+ body as other semantically equivalent body may still
+ throw. */
if (avail <= AVAIL_INTERPOSABLE
|| (!TREE_NOTHROW (y->decl)
- && get_function_state (y)->can_throw))
+ && (get_function_state (y)->can_throw
+ || (opt_for_fn (y->decl, flag_non_call_exceptions)
+ && !e->callee->binds_to_current_def_p (w)))))
can_throw = true;
}
for (ie = w->indirect_calls; ie && !can_throw;
===================================================================
@@ -1111,7 +1111,7 @@ public:
/* Set TREE_NOTHROW on cgraph_node's decl and on aliases of the node
if any to NOTHROW. */
- void set_nothrow_flag (bool nothrow);
+ bool set_nothrow_flag (bool nothrow);
/* If SET_CONST is true, mark function, aliases and thunks to be ECF_CONST.
If SET_CONST if false, clear the flag.
===================================================================
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fnon-call-exceptions -fdump-tree-optimized" } */
+int *ptr;
+static int barvar;
+
+/* We can not detect A to be const because it may be interposed by unoptimized
+ body. */
+inline
+__attribute__ ((noinline))
+int a(void)
+{
+ return *ptr == *ptr;
+}
+main()
+{
+ int aa;
+ ptr = &barvar;
+ try {
+ aa=!a();
+ } catch (...)
+ {
+ return 1;
+ }
+ ptr = 0;
+ return aa;
+}
+/* { dg-final { scan-tree-dump "__cxa_begin_catch" "optimized" } } */