Commit d407e7f5 by Jason Merrill Committed by Jason Merrill

PR c++/82081 - tail call optimization breaks noexcept

If a noexcept function calls a function that might throw, doing the tail
call optimization means that an exception thrown in the called function
will propagate out, breaking the noexcept specification.  So we need to
prevent the optimization in that case.

	* tree-tailcall.c (find_tail_calls): Don't turn a call from a
	nothrow function to a might-throw function into a tail call.

From-SVN: r270656
parent 348dd384
2019-04-29 Jason Merrill <jason@redhat.com>
PR c++/82081 - tail call optimization breaks noexcept
* tree-tailcall.c (find_tail_calls): Don't turn a call from a
nothrow function to a might-throw function into a tail call.
2019-04-29 Richard Sandiford <richard.sandiford@arm.com> 2019-04-29 Richard Sandiford <richard.sandiford@arm.com>
* tree-data-ref.h (data_dependence_relation::inner_loop): Delete. * tree-data-ref.h (data_dependence_relation::inner_loop): Delete.
......
// PR c++/82081
// { dg-do compile { target c++11 } }
// { dg-additional-options "-O2 -fdump-tree-optimized" }
// { dg-final { scan-tree-dump-not "tail call" "optimized" } }
int g(int) ;
int f() noexcept {
int i = 42, j = 43;
return g(i+j);
}
...@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-into-ssa.h" #include "tree-into-ssa.h"
#include "tree-dfa.h" #include "tree-dfa.h"
#include "except.h" #include "except.h"
#include "tree-eh.h"
#include "dbgcnt.h" #include "dbgcnt.h"
#include "cfgloop.h" #include "cfgloop.h"
#include "common/common-target.h" #include "common/common-target.h"
...@@ -472,6 +473,12 @@ find_tail_calls (basic_block bb, struct tailcall **ret) ...@@ -472,6 +473,12 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
&& !auto_var_in_fn_p (ass_var, cfun->decl)) && !auto_var_in_fn_p (ass_var, cfun->decl))
return; return;
/* If the call might throw an exception that wouldn't propagate out of
cfun, we can't transform to a tail or sibling call (82081). */
if (stmt_could_throw_p (cfun, stmt)
&& !stmt_can_throw_external (cfun, stmt))
return;
/* We found the call, check whether it is suitable. */ /* We found the call, check whether it is suitable. */
tail_recursion = false; tail_recursion = false;
func = gimple_call_fndecl (call); func = gimple_call_fndecl (call);
......
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