diff options
author | Jakub Jelinek <jakub@redhat.com> | 2019-05-20 23:33:46 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2019-05-20 23:33:46 +0200 |
commit | 500e4868bf5c89a3136fb329293872d29632ffad (patch) | |
tree | 0176007982f06d3562abe18ff9dd21f58bf4643a /gcc/tree-tailcall.c | |
parent | 3e03ed662651dada81e39d8850da82e80f54fd2d (diff) | |
download | gcc-500e4868bf5c89a3136fb329293872d29632ffad.zip gcc-500e4868bf5c89a3136fb329293872d29632ffad.tar.gz gcc-500e4868bf5c89a3136fb329293872d29632ffad.tar.bz2 |
re PR c++/59813 (tail-call elimination didn't fire for left-shift of char to cout)
PR c++/59813
PR target/90418
* function.h (struct function): Add calls_eh_return member.
* gimplify.c (gimplify_call_expr): Set cfun->calls_eh_return when
gimplifying __builtin_eh_return call.
* tree-inline.c (initialize_cfun): Copy calls_eh_return from src_cfun
to cfun.
(expand_call_inline): Or in src_cfun->calls_eh_return into
dst_cfun->calls_eh_return.
* tree-tailcall.c (suitable_for_tail_call_opt_p): Return false if
cfun->calls_eh_return.
* lto-streamer-in.c (input_struct_function_base): Read calls_eh_return.
* lto-streamer-out.c (output_struct_function_base): Write
calls_eh_return.
From-SVN: r271440
Diffstat (limited to 'gcc/tree-tailcall.c')
-rw-r--r-- | gcc/tree-tailcall.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index f483585..a99cd11 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -140,6 +140,7 @@ suitable_for_tail_opt_p (void) return true; } + /* Returns false when the function is not suitable for tail call optimization for some reason (e.g. if it takes variable number of arguments). This test must pass in addition to suitable_for_tail_opt_p in order to make @@ -168,6 +169,11 @@ suitable_for_tail_call_opt_p (void) if (cfun->calls_setjmp) return false; + /* Various targets don't handle tail calls correctly in functions + that call __builtin_eh_return. */ + if (cfun->calls_eh_return) + return false; + /* ??? It is OK if the argument of a function is taken in some cases, but not in all cases. See PR15387 and PR19616. Revisit for 4.1. */ for (param = DECL_ARGUMENTS (current_function_decl); |