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)