gcc/ PR target/77759 * config/sparc/sparc.c (classify_data_t): Remove unused int_regs field. (classify_registers): Don't set int_regs. (function_arg_slotno): Don't initialise int_regs. Check slotno is within range for empty structs, just like int register-only structs.
gcc/testsuite/ PR target/77759 * g++.dg/other/pr77759.C: New test. --- gcc/config/sparc/sparc.c | 10 +++------- gcc/testsuite/g++.dg/other/pr77759.C | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index c622b66..7af8ba1 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -6294,7 +6294,6 @@ traverse_record_type (const_tree type, bool named, T *data, typedef struct { - bool int_regs; /* true if field eligible to int registers. */ bool fp_regs; /* true if field eligible to FP registers. */ bool fp_regs_in_first_word; /* true if such field in first word. */ } classify_data_t; @@ -6311,8 +6310,6 @@ classify_registers (const_tree, HOST_WIDE_INT bitpos, bool fp, if (bitpos < BITS_PER_WORD) data->fp_regs_in_first_word = true; } - else - data->int_regs = true; } /* Compute the slot number to pass an argument in. @@ -6439,7 +6436,7 @@ function_arg_slotno (const struct sparc_args *cum, machine_mode mode, if (TREE_CODE (type) == RECORD_TYPE) { - classify_data_t data = { false, false, false }; + classify_data_t data = { false, false }; traverse_record_type<classify_data_t, classify_registers> (type, named, &data); @@ -6450,10 +6447,9 @@ function_arg_slotno (const struct sparc_args *cum, machine_mode mode, && slotno >= SPARC_FP_ARG_MAX - 1) return -1; - /* If there are only int args and all int slots are filled, - then must pass on stack. */ + /* If there are only int args or this is an empty record type, + and all int slots are filled, then must pass on stack. */ if (!data.fp_regs - && data.int_regs && slotno >= SPARC_INT_ARG_MAX) return -1; } diff --git a/gcc/testsuite/g++.dg/other/pr77759.C b/gcc/testsuite/g++.dg/other/pr77759.C new file mode 100644 index 0000000..4494bb5 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/pr77759.C @@ -0,0 +1,27 @@ +/* PR target/77759 + This testcase ICEd on sparc because function_arg_slotno did not treat empty + structs as being passed in integer registers and tried to assign the + struct pair_empty to register slot 6, causing function_arg_record_value to + fail the assertion that at least one register was available. */ +/* { dg-do compile { target sparc*-*-* } } */ + +struct empty {}; + +struct pair_empty +{ + struct empty a; + struct empty b; +}; + +void f1(int slot0 __attribute__((unused)), int slot1 __attribute__((unused)), + int slot2 __attribute__((unused)), int slot3 __attribute__((unused)), + int slot4 __attribute__((unused)), int slot5 __attribute__((unused)), + struct pair_empty pair __attribute__((unused))) +{ +} + +void f2(void) +{ + struct pair_empty pair; + f1(0, 0, 0, 0, 0, 0, pair); +} -- 2.9.3