From 19aeedf7af4305455517b87c69681d060f999034 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 19 Jul 2019 04:52:41 -0400 Subject: [PATCH] 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: r273594 --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/tree-ssa/tail-call-1.C | 11 +++++++++++ gcc/tree-tailcall.c | 7 +++++++ 3 files changed, 24 insertions(+) create mode 100644 gcc/testsuite/g++.dg/tree-ssa/tail-call-1.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 22716b0c0c0b..af38e8be96a3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-07-19 Jason Merrill + + 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-07-18 Kito Cheng Backport from mainline 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 000000000000..c67af6e41c72 --- /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 afe8931b5f09..e0265b22dd5f 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); -- 2.47.2