On Tue, Aug 19, 2025 at 6:09 AM Andrew Pinski <andrew.pin...@oss.qualcomm.com> wrote: > > When expanding malloc like functions, we copy the return register into a > temporary > and then mark that temporary register with a noalias regnote and the > alignment. > This works fine unless you are calling the function with a return type of > void. > At this point then the valreg will be null and a crash will happen. > > A few cleanups are included in this patch because it was easier to do the fix > with the cleanups added. > The start_sequence/end_sequence for ECF_MALLOC is no longer needed; I can't > tell > if it was ever needed. > The emit_move_insn function returns the last emitted instruction anyways so > there is no reason to call get_last_insn as we can just use the return value > of emit_move_insn. This has been true since this code was originally added > so I don't understand why it was done that way beforehand. > > Bootstrapped and tested on x86_64-linux-gnu.
OK. Richard. > PR middle-end/120024 > > gcc/ChangeLog: > > * calls.cc (expand_call): Remove start_sequence/end_sequence > for ECF_MALLOC. > Check valreg before deferencing it when it comes to malloc like > functions. Use the return value of emit_move_insn instead of > calling get_last_insn. > > gcc/testsuite/ChangeLog: > > * gcc.dg/torture/malloc-1.c: New test. > * gcc.dg/torture/malloc-2.c: New test. > > Signed-off-by: Andrew Pinski <andrew.pin...@oss.qualcomm.com> > --- > gcc/calls.cc | 19 ++++++------------- > gcc/testsuite/gcc.dg/torture/malloc-1.c | 10 ++++++++++ > gcc/testsuite/gcc.dg/torture/malloc-2.c | 12 ++++++++++++ > 3 files changed, 28 insertions(+), 13 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/torture/malloc-1.c > create mode 100644 gcc/testsuite/gcc.dg/torture/malloc-2.c > > diff --git a/gcc/calls.cc b/gcc/calls.cc > index 2711c4ebe32..bb8a6d09f82 100644 > --- a/gcc/calls.cc > +++ b/gcc/calls.cc > @@ -3235,11 +3235,6 @@ expand_call (tree exp, rtx target, int ignore) > if (pass) > precompute_arguments (num_actuals, args); > > - /* Now we are about to start emitting insns that can be deleted > - if a libcall is deleted. */ > - if (pass && (flags & ECF_MALLOC)) > - start_sequence (); > - > /* Check the canary value for sibcall or function which doesn't > return and could throw. */ > if ((pass == 0 > @@ -3771,25 +3766,23 @@ expand_call (tree exp, rtx target, int ignore) > valreg = gen_rtx_REG (TYPE_MODE (rettype), REGNO (valreg)); > } > > - if (pass && (flags & ECF_MALLOC)) > + /* If the return register exists, for malloc like > + function calls, mark the return register with the > + alignment and noalias reg note. */ > + if (pass && (flags & ECF_MALLOC) && valreg) > { > rtx temp = gen_reg_rtx (GET_MODE (valreg)); > - rtx_insn *last, *insns; > + rtx_insn *last; > > /* The return value from a malloc-like function is a pointer. */ > if (TREE_CODE (rettype) == POINTER_TYPE) > mark_reg_pointer (temp, MALLOC_ABI_ALIGNMENT); > > - emit_move_insn (temp, valreg); > + last = emit_move_insn (temp, valreg); > > /* The return value from a malloc-like function cannot alias > anything else. */ > - last = get_last_insn (); > add_reg_note (last, REG_NOALIAS, temp); > - > - /* Write out the sequence. */ > - insns = end_sequence (); > - emit_insn (insns); > valreg = temp; > } > > diff --git a/gcc/testsuite/gcc.dg/torture/malloc-1.c > b/gcc/testsuite/gcc.dg/torture/malloc-1.c > new file mode 100644 > index 00000000000..ba24153c4f0 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/malloc-1.c > @@ -0,0 +1,10 @@ > +/* { dg-do compile } */ > +/* PR middle-end/120024 */ > + > +void *f(unsigned) __attribute__((malloc)); > +void g() > +{ > + void *(*g)(unsigned) = f; > + void (*h)(unsigned) = (void (*)(unsigned))g; > + h(1); > +} > diff --git a/gcc/testsuite/gcc.dg/torture/malloc-2.c > b/gcc/testsuite/gcc.dg/torture/malloc-2.c > new file mode 100644 > index 00000000000..8eeca9d7add > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/malloc-2.c > @@ -0,0 +1,12 @@ > +/* { dg-do compile } */ > +/* PR middle-end/120024 */ > + > +void *f(unsigned) __attribute__((malloc)); > +void h1(void); > +void g(void) > +{ > + void *(*g)(unsigned) = f; > + void (*h)(unsigned) = (void (*)(unsigned))g; > + h(1); > + h1(); > +} > -- > 2.43.0 >