On Tue, 22 Mar 2022, Jakub Jelinek wrote:

> Hi!
> 
> On Mon, Feb 28, 2022 at 07:52:56AM -0000, Roger Sayle wrote:
> > This patch resolves PR c++/84964 which is an ICE in the middle-end after
> > emitting a "sorry, unimplemented" message, and is a regression from
> > earlier releases of GCC.  This issue is that after encountering a
> > function call requiring an unreasonable amount of stack space, the
> > code continues and falls foul of an assert checking that stack pointer
> > has been correctly updated.  The fix is to (locally) consider aborted
> > function calls as "no return", which skips this downstream sanity check.
> 
> As can be seen on PR104989, just setting ECF_NORETURN after sorry is quite
> risky and leads to other ICEs.  The problem is that ECF_NORETURN calls
> better should be at the end of basic blocks that don't have any fallthru
> successor edges, otherwise we can ICE later.
> 
> This patch instead sets sibcall_failure if in pass == 0 (sibcall_failure
> means that the tail call sequence is not useful/not desirable and throws
> it away) and otherwise sets a new bool variable that will let us pass
> the assertion and also throws away the whole call sequence, I think that is
> best for error recovery.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

> 2022-03-22  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR rtl-optimization/104989
>       * calls.cc (expand_call): Don't set ECF_NORETURN in flags after
>       sorry for passing too large argument, instead set sibcall_failure
>       for pass == 0, or a new normal_failure flag otherwise.  If
>       normal_failure is set, don't assert all stack has been deallocated
>       at the end and throw away the whole insn sequence.
> 
>       * g++.dg/other/pr104989.C: New test.
> 
> --- gcc/calls.cc.jj   2022-03-11 13:11:53.613095003 +0100
> +++ gcc/calls.cc      2022-03-21 11:21:52.997671148 +0100
> @@ -3068,6 +3068,7 @@ expand_call (tree exp, rtx target, int i
>    for (pass = try_tail_call ? 0 : 1; pass < 2; pass++)
>      {
>        int sibcall_failure = 0;
> +      bool normal_failure = false;
>        /* We want to emit any pending stack adjustments before the tail
>        recursion "call".  That way we know any adjustment after the tail
>        recursion call can be ignored if we indeed use the tail
> @@ -3448,7 +3449,10 @@ expand_call (tree exp, rtx target, int i
>               {
>                 sorry ("passing too large argument on stack");
>                 /* Don't worry about stack clean-up.  */
> -               flags |= ECF_NORETURN;
> +               if (pass == 0)
> +                 sibcall_failure = 1;
> +               else
> +                 normal_failure = true;
>                 continue;
>               }
>  
> @@ -3905,9 +3909,12 @@ expand_call (tree exp, rtx target, int i
>  
>         /* Verify that we've deallocated all the stack we used.  */
>         gcc_assert ((flags & ECF_NORETURN)
> +                   || normal_failure
>                     || known_eq (old_stack_allocated,
>                                  stack_pointer_delta
>                                  - pending_stack_adjust));
> +       if (normal_failure)
> +         normal_call_insns = NULL;
>       }
>  
>        /* If something prevents making this a sibling call,
> --- gcc/testsuite/g++.dg/other/pr104989.C.jj  2022-03-21 11:19:41.633496189 
> +0100
> +++ gcc/testsuite/g++.dg/other/pr104989.C     2022-03-21 11:20:08.248126431 
> +0100
> @@ -0,0 +1,9 @@
> +// PR rtl-optimization/104989
> +// { dg-do compile }
> +// { dg-options "-fnon-call-exceptions" }
> +
> +struct a {
> +  short b : -1ULL;
> +};
> +void c(...) { c(a()); }
> +// { dg-excess-errors "" }
> 
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Ivo Totev; HRB 36809 (AG Nuernberg)

Reply via email to