https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77759
Bug ID: 77759 Summary: internal compiler error: in function_arg_record_value Product: gcc Version: 6.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: jrtc27 at jrtc27 dot com Target Milestone: --- Source: struct empty {}; struct pair_empty { struct empty a; struct empty b; }; void f(int slot0, int slot1, int slot2, int slot3, int slot4, int slot5, struct pair_empty pair) { } int main(int argc, char **argv) { struct pair_empty pair; f(0, 0, 0, 0, 0, 0, pair); return 0; } With g++ 6.2.0 in Debian unstable: main.cpp: In function ‘void f(int, int, int, int, int, int, pair_empty)’: main.cpp:8:6: internal compiler error: in function_arg_record_value, at config/sparc/sparc.c:6729 void f(int slot0, int slot1, int slot2, int slot3, int slot4, int slot5, struct pair_empty pair) { ^ 0xa3bf7f function_arg_record_value ../../src/gcc/config/sparc/sparc.c:6729 0xa3c5bb sparc_function_arg_1 ../../src/gcc/config/sparc/sparc.c:6879 0x58ea7b assign_parm_find_entry_rtl ../../src/gcc/function.c:2534 0x58ea7b assign_parms ../../src/gcc/function.c:3723 0x590537 expand_function_start(tree_node*) ../../src/gcc/function.c:5207 0x465243 execute ../../src/gcc/cfgexpand.c:6225 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <file:///usr/share/doc/gcc-6/README.Bugs> for instructions. With g++ 7.0.0 20160927 from master (7469707ce8cf1d74002118cdca992650998d4acd): main.cpp: In function ‘void f(int, int, int, int, int, int, pair_empty)’: main.cpp:8:6: internal compiler error: in function_arg_record_value, at config/sparc/sparc.c:6739 void f(int slot0, int slot1, int slot2, int slot3, int slot4, int slot5, struct pair_empty pair) { ^ 0xdd8f4f function_arg_record_value ../../upstream/gcc/config/sparc/sparc.c:6739 0xdd9dbb sparc_function_arg_1 ../../upstream/gcc/config/sparc/sparc.c:6889 0x79fe93 assign_parm_find_entry_rtl ../../upstream/gcc/function.c:2532 0x79fe93 assign_parms ../../upstream/gcc/function.c:3725 0x7a2ae3 expand_function_start(tree_node*) ../../upstream/gcc/function.c:5209 0x61c5cf execute ../../upstream/gcc/cfgexpand.c:6256 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. function_arg_slotno gets to the MODE_RANDOM case, and follows the `TARGET_ARCH64 && type` branch. traverse_record_type walks over the the pair_empty type, but as there are no actual fields (only other records which are traversed), classify_registers is never called, so data remains { false, false, false }. Thus, neither of the conditions for returning -1 for records are satisfied, and so slotno (which is 6) is returned. Then, in function_arg_record_value, it takes the `nregs == 0` branch (since traverse_record_type never calls count_registers for the same reason as above), tries nregs = 1, but then hits the `nregs + slotno > SPARC_INT_ARG_MAX` branch, and so nregs gets set to `SPARC_INT_ARG_MAX - slotno`, which is 0 in this case (and would be negative if more ints were added to f to fill up the slots). Then, the gcc_assert(nregs > 0) fails and gives the above backtrace. The following patch fixes this; thoughts? --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -6450,10 +6450,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; }