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
+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.
--- /dev/null
+// 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);
+}
#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"
&& !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);