On Mon, Jan 26, 2026 at 6:42 AM Andrew Pinski <[email protected]> wrote: > > output_asm_insn has an out of bounds array access if the supplied > operand number in the inline-asm is "big" (>=MAX_RECOG_OPERANDS). > This makes it so that there is no longer an out of bounds access > by increasing the two arrays by one and using the last element as > the fake location for all out of range operands. > > This could be a regression because r0-38026-g4f9b4029463bc0 seems like > introduce the out of bounds access but > > Bootstrapped and tested on x86_64-linux-gnu.
OK. I wonder if this will make it for an interesting class of new ice-on-invalid? But I suppose you've explored different options. Thanks, Richard. > PR middle-end/123709 > > gcc/ChangeLog: > > * final.cc (output_asm_operand_names): Skip over > opnum which is MAX_RECOG_OPERANDS (invalid). > (output_asm_insn): Increase opoutput and oporder size > by 1. For out of range operands, set the opnum to > MAX_RECOG_OPERANDS. > > gcc/testsuite/ChangeLog: > > * c-c++-common/asm-invalid-operand-1.c: New test. > > Signed-off-by: Andrew Pinski <[email protected]> > --- > gcc/final.cc | 22 ++++++++++++++----- > .../c-c++-common/asm-invalid-operand-1.c | 11 ++++++++++ > 2 files changed, 28 insertions(+), 5 deletions(-) > create mode 100644 gcc/testsuite/c-c++-common/asm-invalid-operand-1.c > > diff --git a/gcc/final.cc b/gcc/final.cc > index f376f12e5a8..b5e8c6e2efd 100644 > --- a/gcc/final.cc > +++ b/gcc/final.cc > @@ -3295,7 +3295,11 @@ output_asm_operand_names (rtx *operands, int *oporder, > int nops) > for (i = 0; i < nops; i++) > { > int addressp; > - rtx op = operands[oporder[i]]; > + int opnum = oporder[i]; > + /* Skip invalid ops. */ > + if (opnum == MAX_RECOG_OPERANDS) > + continue; > + rtx op = operands[opnum]; > tree expr = get_mem_expr_from_op (op, &addressp); > > fprintf (asm_out_file, "%c%s", > @@ -3428,8 +3432,8 @@ output_asm_insn (const char *templ, rtx *operands) > #ifdef ASSEMBLER_DIALECT > int dialect = 0; > #endif > - int oporder[MAX_RECOG_OPERANDS]; > - char opoutput[MAX_RECOG_OPERANDS]; > + int oporder[MAX_RECOG_OPERANDS+1]; > + char opoutput[MAX_RECOG_OPERANDS+1]; > int ops = 0; > > /* An insn may return a null string template > @@ -3517,7 +3521,11 @@ output_asm_insn (const char *templ, rtx *operands) > output_operand_lossage ("operand number missing " > "after %%-letter"); > else if (this_is_asm_operands && opnum >= insn_noperands) > - output_operand_lossage ("operand number out of range"); > + { > + /* Force the opnum in bounds to a bogus location. */ > + opnum = MAX_RECOG_OPERANDS; > + output_operand_lossage ("operand number out of range"); > + } > else if (letter == 'l') > output_asm_label (operands[opnum]); > else if (letter == 'a') > @@ -3558,7 +3566,11 @@ output_asm_insn (const char *templ, rtx *operands) > > opnum = strtoul (p, &endptr, 10); > if (this_is_asm_operands && opnum >= insn_noperands) > - output_operand_lossage ("operand number out of range"); > + { > + /* Force the opnum in bounds to a bogus location. */ > + opnum = MAX_RECOG_OPERANDS; > + output_operand_lossage ("operand number out of range"); > + } > else > output_operand (operands[opnum], 0); > > diff --git a/gcc/testsuite/c-c++-common/asm-invalid-operand-1.c > b/gcc/testsuite/c-c++-common/asm-invalid-operand-1.c > new file mode 100644 > index 00000000000..d8dc79f17a0 > --- /dev/null > +++ b/gcc/testsuite/c-c++-common/asm-invalid-operand-1.c > @@ -0,0 +1,11 @@ > +/* { dg-do compile } */ > +/* { dg-options "" } */ > +/* PR middle-end/123709 */ > + > +int test1(int a) { > + asm volatile("%i\n" /* { dg-error "operand number out of range" } */ > + "505x" > + : > + : "r"(a)); > + return a; > +} > -- > 2.43.0 >
