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
>

Reply via email to