diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tree-ssa/tail-call-1.C | 11 | ||||
-rw-r--r-- | gcc/tree-tailcall.c | 7 |
3 files changed, 24 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e548281..b4554f6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +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> * tree-data-ref.h (data_dependence_relation::inner_loop): Delete. diff --git a/gcc/testsuite/g++.dg/tree-ssa/tail-call-1.C b/gcc/testsuite/g++.dg/tree-ssa/tail-call-1.C new file mode 100644 index 0000000..c67af6e --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/tail-call-1.C @@ -0,0 +1,11 @@ +// 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); +} diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index afe8931..e0265b2 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-into-ssa.h" #include "tree-dfa.h" #include "except.h" +#include "tree-eh.h" #include "dbgcnt.h" #include "cfgloop.h" #include "common/common-target.h" @@ -472,6 +473,12 @@ find_tail_calls (basic_block bb, struct tailcall **ret) && !auto_var_in_fn_p (ass_var, cfun->decl)) 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. */ tail_recursion = false; func = gimple_call_fndecl (call); |