public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
* [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw @ 2020-04-26 9:17 sbence92 at gmail dot com 2020-04-26 15:15 ` [Bug target/94770] " jakub at gcc dot gnu.org ` (13 more replies) 0 siblings, 14 replies; 15+ messages in thread From: sbence92 at gmail dot com @ 2020-04-26 9:17 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770 Bug ID: 94770 Summary: class with empty base passed incorrectly with -std=c++17 on mingw Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: sbence92 at gmail dot com Target Milestone: --- Created attachment 48376 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48376&action=edit preprocessed failing tests Similar to Bug #94383, Bug #94704 and Bug #94706 the below tests fail with gcc 10 (ead1c27a530) with mingw host and target (also with gcc 9.3 taken from msys2). FAIL: tmpdir-g++.dg-struct-layout-1/t032 cp_compat_x_tst.o-cp_compat_y_tst.o execute FAIL: tmpdir-g++.dg-struct-layout-1/t033 cp_compat_x_tst.o-cp_compat_y_tst.o execute FAIL: tmpdir-g++.dg-struct-layout-1/t034 cp_compat_x_tst.o-cp_compat_y_tst.o execute FAIL: tmpdir-g++.dg-struct-layout-1/t051 cp_compat_x_tst.o-cp_compat_y_tst.o execute FAIL: tmpdir-g++.dg-struct-layout-1/t055 cp_compat_x_tst.o-cp_compat_y_tst.o execute FAIL: tmpdir-g++.dg-struct-layout-1/t056 cp_compat_x_tst.o-cp_compat_y_tst.o execute FAIL: tmpdir-g++.dg-struct-layout-1/t058 cp_compat_x_tst.o-cp_compat_y_tst.o execute FAIL: tmpdir-g++.dg-struct-layout-1/t059 cp_compat_x_tst.o-cp_compat_y_tst.o execute tmpdir-g++-dg-struct-layout-1-t032-01.exe fail 30.71 tmpdir-g++-dg-struct-layout-1-t033-01.exe fail 385.71 tmpdir-g++-dg-struct-layout-1-t034-01.exe fail 798.71 tmpdir-g++-dg-struct-layout-1-t051-01.exe fail 1817.71 tmpdir-g++-dg-struct-layout-1-t055-01.exe fail 2002.71 tmpdir-g++-dg-struct-layout-1-t056-01.exe fail 2200.71 tmpdir-g++-dg-struct-layout-1-t058-01.exe fail 2604.71 tmpdir-g++-dg-struct-layout-1-t059-01.exe fail 2828.71 ^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug target/94770] class with empty base passed incorrectly with -std=c++17 on mingw 2020-04-26 9:17 [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw sbence92 at gmail dot com @ 2020-04-26 15:15 ` jakub at gcc dot gnu.org 2020-04-26 20:44 ` sbence92 at gmail dot com ` (12 subsequent siblings) 13 siblings, 0 replies; 15+ messages in thread From: jakub at gcc dot gnu.org @ 2020-04-26 15:15 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770 Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Does gcc/testsuite/g++/g++.dg-struct-layout-1/t032_test.h in build directory contain T(30,struct{}a[1];,) ? Failure 71 suggests different parameter passing on something like: void foo (int, ...); struct empty_base {}; struct S : public empty_base { struct{}a[1]; }; S s, a[5]; void bar () { foo (1, 1.0, s, 2LL, a[2], a[2]); } but my cross-compiler generates the same code with -std=c++14 and -std=c++17 here. ^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug target/94770] class with empty base passed incorrectly with -std=c++17 on mingw 2020-04-26 9:17 [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw sbence92 at gmail dot com 2020-04-26 15:15 ` [Bug target/94770] " jakub at gcc dot gnu.org @ 2020-04-26 20:44 ` sbence92 at gmail dot com 2020-04-26 20:45 ` sbence92 at gmail dot com ` (11 subsequent siblings) 13 siblings, 0 replies; 15+ messages in thread From: sbence92 at gmail dot com @ 2020-04-26 20:44 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770 --- Comment #2 from Bence Szabó <sbence92 at gmail dot com> --- Yes there's a T(30,struct{}a[1];,) in t032. Indeed the fail happens on a variadic function (void check30va(int i, ...)). I dig in some more and it turns out all the tests listed crash. I've attached the formated preprocessed source for t032. ^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug target/94770] class with empty base passed incorrectly with -std=c++17 on mingw 2020-04-26 9:17 [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw sbence92 at gmail dot com 2020-04-26 15:15 ` [Bug target/94770] " jakub at gcc dot gnu.org 2020-04-26 20:44 ` sbence92 at gmail dot com @ 2020-04-26 20:45 ` sbence92 at gmail dot com 2020-04-26 21:26 ` sbence92 at gmail dot com ` (10 subsequent siblings) 13 siblings, 0 replies; 15+ messages in thread From: sbence92 at gmail dot com @ 2020-04-26 20:45 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770 --- Comment #3 from Bence Szabó <sbence92 at gmail dot com> --- Created attachment 48379 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48379&action=edit t032 ^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug target/94770] class with empty base passed incorrectly with -std=c++17 on mingw 2020-04-26 9:17 [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw sbence92 at gmail dot com ` (2 preceding siblings ...) 2020-04-26 20:45 ` sbence92 at gmail dot com @ 2020-04-26 21:26 ` sbence92 at gmail dot com 2020-04-26 21:28 ` jakub at gcc dot gnu.org ` (9 subsequent siblings) 13 siblings, 0 replies; 15+ messages in thread From: sbence92 at gmail dot com @ 2020-04-26 21:26 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770 --- Comment #4 from Bence Szabó <sbence92 at gmail dot com> --- As a remark for 'same code with -std=c++14 and -std=c++17 here', I can confirm, the example you provided also produces same assembly for me in c++14 and c++17. Also compiling t032 with only c++14 or only c++17 still results in a failing test case (30.71) and then a crash. Maybe this is not the same abi problem? ^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug target/94770] class with empty base passed incorrectly with -std=c++17 on mingw 2020-04-26 9:17 [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw sbence92 at gmail dot com ` (3 preceding siblings ...) 2020-04-26 21:26 ` sbence92 at gmail dot com @ 2020-04-26 21:28 ` jakub at gcc dot gnu.org 2020-04-27 7:50 ` sbence92 at gmail dot com ` (8 subsequent siblings) 13 siblings, 0 replies; 15+ messages in thread From: jakub at gcc dot gnu.org @ 2020-04-26 21:28 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770 --- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Bence Szabó from comment #4) > As a remark for 'same code with -std=c++14 and -std=c++17 here', I can > confirm, the example you provided also produces same assembly for me in > c++14 and c++17. > Also compiling t032 with only c++14 or only c++17 still results in a failing > test case (30.71) and then a crash. Maybe this is not the same abi problem? Ah, then it is not c++14 vs. c++17 ABI incompatibility, but some bug in va_arg passing of such classes for mingw. ^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug target/94770] class with empty base passed incorrectly with -std=c++17 on mingw 2020-04-26 9:17 [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw sbence92 at gmail dot com ` (4 preceding siblings ...) 2020-04-26 21:28 ` jakub at gcc dot gnu.org @ 2020-04-27 7:50 ` sbence92 at gmail dot com 2020-04-27 9:51 ` jakub at gcc dot gnu.org ` (7 subsequent siblings) 13 siblings, 0 replies; 15+ messages in thread From: sbence92 at gmail dot com @ 2020-04-27 7:50 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770 --- Comment #6 from Bence Szabó <sbence92 at gmail dot com> --- > Ah, then it is not c++14 vs. c++17 ABI incompatibility, but some bug in > va_arg passing of such classes for mingw. It seems so. In t032 I got rid of the crashing tests (30, 56, 77, 80, 89, 100, 117, 134, 162, 171, 174, 191, 250 all of them are the second variadic test case) and the rest of the tests pass in t032. Same in t059: 2998, 2828 crash on 2nd variadic test the rest passes. Sorry for misleading bug report, I saw the same test cases fail as the mentioned reports, didn't know the reason is so different. ^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug target/94770] class with empty base passed incorrectly with -std=c++17 on mingw 2020-04-26 9:17 [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw sbence92 at gmail dot com ` (5 preceding siblings ...) 2020-04-27 7:50 ` sbence92 at gmail dot com @ 2020-04-27 9:51 ` jakub at gcc dot gnu.org 2020-04-27 10:49 ` redi at gcc dot gnu.org ` (6 subsequent siblings) 13 siblings, 0 replies; 15+ messages in thread From: jakub at gcc dot gnu.org @ 2020-04-27 9:51 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770 --- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So, does: struct empty_base {}; struct S : public empty_base { struct{}a[1]; }; S s, a[5]; __attribute__((noipa)) void foo (int x, ...) { __builtin_va_list ap; __builtin_va_start (ap, x); if (x != 1 && x != 2) __builtin_abort (); if (__builtin_va_arg (ap, double) != 1.0) __builtin_abort (); if (x == 1) __builtin_va_arg (ap, S); if (__builtin_va_arg (ap, long long) != 2LL) __builtin_abort (); if (x == 1) { __builtin_va_arg (ap, S); __builtin_va_arg (ap, S); } __builtin_va_end (ap); } int main () { foo (1, 1.0, s, 2LL, a[2], a[2]); foo (2, 1.0, 2LL); } FAIL too? Seems the va_arg (sp, S); don't do anything, i.e. not to expect the empty class with empty base to be passed at all, but on the caller side it makes a change: The first arg is passed in %ecx, second in both %xmm1 and %rdx it seems, and 2LL is passed in %r9 in the first call to foo and in $r8 in the second one. Now, the question is what MSCV or other compilers do (e.g. clang), if they match what GCC does on the caller side, or on the va_arg side (guess one needs to sed -i -e 's/__builtin_//g;s/__attribute__((noipa)) //' in the testcase, and add #include <cstdarg> and #include <cstdlib>. Seems even empty bases aren't needed, as struct S { struct{}a[1]; }; is treated the same, or even just struct S {}; ^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug target/94770] class with empty base passed incorrectly with -std=c++17 on mingw 2020-04-26 9:17 [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw sbence92 at gmail dot com ` (6 preceding siblings ...) 2020-04-27 9:51 ` jakub at gcc dot gnu.org @ 2020-04-27 10:49 ` redi at gcc dot gnu.org 2020-04-27 10:50 ` redi at gcc dot gnu.org ` (5 subsequent siblings) 13 siblings, 0 replies; 15+ messages in thread From: redi at gcc dot gnu.org @ 2020-04-27 10:49 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770 --- Comment #8 from Jonathan Wakely <redi at gcc dot gnu.org> --- The third __builtin_abort() is called: if (__builtin_va_arg (ap, long long) != 2LL) __builtin_abort (); ^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug target/94770] class with empty base passed incorrectly with -std=c++17 on mingw 2020-04-26 9:17 [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw sbence92 at gmail dot com ` (7 preceding siblings ...) 2020-04-27 10:49 ` redi at gcc dot gnu.org @ 2020-04-27 10:50 ` redi at gcc dot gnu.org 2020-04-27 11:04 ` jakub at gcc dot gnu.org ` (4 subsequent siblings) 13 siblings, 0 replies; 15+ messages in thread From: redi at gcc dot gnu.org @ 2020-04-27 10:50 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770 --- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> --- At least, when using: gcc version 9.2.1 20190827 (Fedora MinGW 9.2.1-1.fc31) (GCC) and executing with Wine. ^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug target/94770] class with empty base passed incorrectly with -std=c++17 on mingw 2020-04-26 9:17 [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw sbence92 at gmail dot com ` (8 preceding siblings ...) 2020-04-27 10:50 ` redi at gcc dot gnu.org @ 2020-04-27 11:04 ` jakub at gcc dot gnu.org 2020-04-27 11:41 ` jakub at gcc dot gnu.org ` (3 subsequent siblings) 13 siblings, 0 replies; 15+ messages in thread From: jakub at gcc dot gnu.org @ 2020-04-27 11:04 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770 --- Comment #10 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Jonathan Wakely from comment #9) > At least, when using: > gcc version 9.2.1 20190827 (Fedora MinGW 9.2.1-1.fc31) (GCC) > and executing with Wine. Yeah, I can clearly see it in the assembly that it must ICE, the big question is what is the right ABI, if the empty structures are not passed at all (like e.g. in the x86-64 clarified psABI), or if they are passed as clearly is what happens in the caller. On the va_arg side, for the MS ABI va_list seems to be a pointer and thus it defers to the standard middle-end handling where it see a TYPE_EMPTY_P? struct and uses 0 size instead of the actual one. Now, not sure if we can tweak the *RECORD_EMPTY_P* target hook, because it marks types rather than their uses, and in sources where both x86-64 psABI and msabi are used together, we want TYPE_EMPTY_P being set for the former and perhaps not? for the latter. Of course, the backend coiuld check for the MSABI and TYPE_EMPTY_P type and don't defer to the middle-end in that case and handle it differently. BTW, when I tried clang++ (10.0.0 trunk 374035 version) with -target x86_64-w64-mingw32, it seems it matches g++ on the caller side and does something on the callee side, but I bet MSVC is the ABI etalon on this target, right? ^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug target/94770] class with empty base passed incorrectly with -std=c++17 on mingw 2020-04-26 9:17 [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw sbence92 at gmail dot com ` (9 preceding siblings ...) 2020-04-27 11:04 ` jakub at gcc dot gnu.org @ 2020-04-27 11:41 ` jakub at gcc dot gnu.org 2020-04-27 11:48 ` jakub at gcc dot gnu.org ` (2 subsequent siblings) 13 siblings, 0 replies; 15+ messages in thread From: jakub at gcc dot gnu.org @ 2020-04-27 11:41 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770 Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |mpolacek at gcc dot gnu.org --- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> --- I've tried to unconditionally return false; from ix86_is_empty_record and that then keeps pretty much same ABI on the caller side and changes the va_arg handling to do the needed adjustments. Which might mean this is a regression since r255066. Though, the big question still is what the msabi wants. And if it wants to pass these empty classes as their padding, then we probably need to make sure the middle-end doesn't use TYPE_EMPTY_P at all, but instead it uses a new target hook to which it would pass the type and some way how to identify what ABI it cares about (say NULL for the current function's ABI and a fndecl if it is calling some other function and wants that other function's ABI), and the hook would then either return TYPE_EMPTY_P for non-msabi, or false for msabi. ^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug target/94770] class with empty base passed incorrectly with -std=c++17 on mingw 2020-04-26 9:17 [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw sbence92 at gmail dot com ` (10 preceding siblings ...) 2020-04-27 11:41 ` jakub at gcc dot gnu.org @ 2020-04-27 11:48 ` jakub at gcc dot gnu.org 2020-04-27 12:27 ` jakub at gcc dot gnu.org 2020-05-09 19:37 ` sbence92 at gmail dot com 13 siblings, 0 replies; 15+ messages in thread From: jakub at gcc dot gnu.org @ 2020-04-27 11:48 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770 --- Comment #12 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Another interesting test is: struct S {}; void foo (int, int, int, int, int, int, int, int, int, S, S, S, S, int); void baz (int, int, int, int, int, int, int, int, int, int); int bar () { foo (1, 2, 3, 4, 5, 6, 7, 8, 9, S {}, S {}, S {}, S {}, 10); baz (1, 2, 3, 4, 5, 6, 7, 8, 9, 10); return 0; } The question is, is 10 passed in the same stack slot to both foo and baz or not? In current GCC it is, with the unconditional return false; in ix86_is_empty_record it is not, and with that clang++10 snapshot it is not either. So, what does MSVC do here? ^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug target/94770] class with empty base passed incorrectly with -std=c++17 on mingw 2020-04-26 9:17 [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw sbence92 at gmail dot com ` (11 preceding siblings ...) 2020-04-27 11:48 ` jakub at gcc dot gnu.org @ 2020-04-27 12:27 ` jakub at gcc dot gnu.org 2020-05-09 19:37 ` sbence92 at gmail dot com 13 siblings, 0 replies; 15+ messages in thread From: jakub at gcc dot gnu.org @ 2020-04-27 12:27 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770 --- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Completely untested WIP patch: --- gcc/config/i386/i386.c.jj 2020-04-27 13:50:39.529692389 +0200 +++ gcc/config/i386/i386.c 2020-04-27 14:03:12.479322957 +0200 @@ -16550,6 +16550,23 @@ ix86_is_empty_record (const_tree type) return default_is_empty_record (type); } +/* Implement TARGET_EMPTY_TYPE_P. */ + +static bool +ix86_empty_type_p (const_tree fntype, const_tree type) +{ + if (!TYPE_EMPTY_P (type)) + return false; + if (fntype) + { + if (ix86_function_type_abi (fntype) == MS_ABI) + return false; + } + else if (ix86_cfun_abi () == MS_ABI) + return false; + return true; +} + /* Implement TARGET_WARN_PARAMETER_PASSING_ABI. */ static void @@ -23470,6 +23487,8 @@ ix86_run_selftests (void) #undef TARGET_EMPTY_RECORD_P #define TARGET_EMPTY_RECORD_P ix86_is_empty_record +#undef TARGET_EMPTY_TYPE_P +#define TARGET_EMPTY_TYPE_P ix86_empty_type_p #undef TARGET_WARN_PARAMETER_PASSING_ABI #define TARGET_WARN_PARAMETER_PASSING_ABI ix86_warn_parameter_passing_abi --- gcc/function.c.jj 2020-04-16 10:15:06.841126753 +0200 +++ gcc/function.c 2020-04-27 14:21:27.669799119 +0200 @@ -2102,7 +2102,7 @@ aggregate_value_p (const_tree exp, const if (TREE_ADDRESSABLE (type)) return 1; - if (TYPE_EMPTY_P (type)) + if (targetm.calls.empty_type_p (fntype, type)) return 0; if (flag_pcc_struct_return && AGGREGATE_TYPE_P (type)) @@ -3095,7 +3095,8 @@ assign_parm_setup_block (struct assign_p move_block_from_reg (REGNO (entry_parm), mem, size_stored / UNITS_PER_WORD); } - else if (data->stack_parm == 0 && !TYPE_EMPTY_P (data->arg.type)) + else if (data->stack_parm == 0 + && !targetm.calls.empty_type_p (NULL_TREE, data->arg.type)) { push_to_sequence2 (all->first_conversion_insn, all->last_conversion_insn); emit_block_move (stack_parm, data->entry_parm, GEN_INT (size), @@ -3496,7 +3497,7 @@ assign_parm_setup_stack (struct assign_p dest = validize_mem (copy_rtx (data->stack_parm)); src = validize_mem (copy_rtx (data->entry_parm)); - if (TYPE_EMPTY_P (data->arg.type)) + if (targetm.calls.empty_type_p (NULL_TREE, data->arg.type)) /* Empty types don't really need to be copied. */; else if (MEM_P (src)) { @@ -3657,7 +3658,7 @@ assign_parms (tree fndecl) passing area, have non-zero size and have address taken, force creation of a stack slot so that they have distinct address from other parameters. */ - if (TYPE_EMPTY_P (data.arg.type) + if (targetm.calls.empty_type_p (NULL_TREE, data.arg.type) && TREE_ADDRESSABLE (parm) && data.entry_parm == data.stack_parm && MEM_P (data.entry_parm) --- gcc/targhooks.h.jj 2020-01-12 11:54:36.939405473 +0100 +++ gcc/targhooks.h 2020-04-27 13:57:13.113741631 +0200 @@ -246,6 +246,7 @@ extern unsigned int default_dwarf_poly_i int *); extern machine_mode default_dwarf_frame_reg_mode (int); extern fixed_size_mode default_get_reg_raw_mode (int); +extern bool default_empty_type_p (const_tree, const_tree); extern bool default_keep_leaf_when_profiled (); extern void *default_get_pch_validity (size_t *); --- gcc/targhooks.c.jj 2020-01-21 09:14:07.566267369 +0100 +++ gcc/targhooks.c 2020-04-27 14:07:27.228481737 +0200 @@ -1945,6 +1945,12 @@ default_get_reg_raw_mode (int regno) return as_a <fixed_size_mode> (reg_raw_mode[regno]); } +bool +default_empty_type_p (const_tree, const_tree type) +{ + return TYPE_EMPTY_P (type); +} + /* Return true if a leaf function should stay leaf even with profiling enabled. */ @@ -2190,7 +2196,7 @@ std_gimplify_va_arg_expr (tree valist, t /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually requires greater alignment, we must perform dynamic alignment. */ if (boundary > align - && !TYPE_EMPTY_P (type) + && !targetm.calls.empty_type_p (NULL_TREE, type) && !integer_zerop (TYPE_SIZE (type))) { t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, --- gcc/calls.c.jj 2020-04-27 09:10:50.593968911 +0200 +++ gcc/calls.c 2020-04-27 14:12:14.046156465 +0200 @@ -146,12 +146,13 @@ static unsigned HOST_WIDE_INT stored_arg static int stack_arg_under_construction; static void precompute_register_parameters (int, struct arg_data *, int *); -static int store_one_arg (struct arg_data *, rtx, int, int, int); +static int store_one_arg (const_tree, struct arg_data *, rtx, int, int, int); static void store_unaligned_arguments_into_pseudos (struct arg_data *, int); static int finalize_must_preallocate (int, int, struct arg_data *, struct args_size *); static void precompute_arguments (int, struct arg_data *); -static void compute_argument_addresses (struct arg_data *, rtx, int); +static void compute_argument_addresses (const_tree, struct arg_data *, rtx, + int); static rtx rtx_for_function_call (tree, tree); static void load_register_parameters (struct arg_data *, int, rtx *, int, int, int *); @@ -2769,7 +2770,8 @@ finalize_must_preallocate (int must_prea ARGBLOCK is an rtx for the address of the outgoing arguments. */ static void -compute_argument_addresses (struct arg_data *args, rtx argblock, int num_actuals) +compute_argument_addresses (const_tree funtype, struct arg_data *args, + rtx argblock, int num_actuals) { if (argblock) { @@ -2798,7 +2800,8 @@ compute_argument_addresses (struct arg_d && args[i].partial == 0) continue; - if (TYPE_EMPTY_P (TREE_TYPE (args[i].tree_value))) + if (targetm.calls.empty_type_p (funtype, + TREE_TYPE (args[i].tree_value))) continue; addr = simplify_gen_binary (PLUS, Pmode, arg_reg, offset); @@ -4384,7 +4387,7 @@ expand_call (tree exp, rtx target, int i } } - compute_argument_addresses (args, argblock, num_actuals); + compute_argument_addresses (funtype, args, argblock, num_actuals); /* Stack is properly aligned, pops can't safely be deferred during the evaluation of the arguments. */ @@ -4473,7 +4476,7 @@ expand_call (tree exp, rtx target, int i continue; } - if (store_one_arg (&args[i], argblock, flags, + if (store_one_arg (funtype, &args[i], argblock, flags, adjusted_args_size.var != 0, reg_parm_stack_space) || (pass == 0 @@ -4513,7 +4516,7 @@ expand_call (tree exp, rtx target, int i break; } - if (store_one_arg (&args[i], argblock, flags, + if (store_one_arg (funtype, &args[i], argblock, flags, adjusted_args_size.var != 0, reg_parm_stack_space) || (pass == 0 @@ -5845,8 +5848,9 @@ emit_library_call_value_1 (int retval, r zero otherwise. */ static int -store_one_arg (struct arg_data *arg, rtx argblock, int flags, - int variable_size ATTRIBUTE_UNUSED, int reg_parm_stack_space) +store_one_arg (const_tree funtype, struct arg_data *arg, rtx argblock, + int flags, int variable_size ATTRIBUTE_UNUSED, + int reg_parm_stack_space) { tree pval = arg->tree_value; rtx reg = 0; @@ -6016,7 +6020,7 @@ store_one_arg (struct arg_data *arg, rtx Note that in C the default argument promotions will prevent such mismatches. */ - poly_int64 size = (TYPE_EMPTY_P (TREE_TYPE (pval)) + poly_int64 size = (targetm.calls.empty_type_p (funtype, TREE_TYPE (pval)) ? 0 : GET_MODE_SIZE (arg->mode)); /* Compute how much space the push instruction will push. --- gcc/doc/tm.texi.jj 2020-03-17 13:50:52.844934839 +0100 +++ gcc/doc/tm.texi 2020-04-27 14:17:07.848721305 +0200 @@ -4693,6 +4693,12 @@ This target hook returns true if the typ is to return @code{false}. @end deftypefn +@deftypefn {Target Hook} bool TARGET_EMPTY_TYPE_P (const_tree @var{fndecl}, const_tree @var{type}) +This target hook returns true if the type is an empty record in the ABI +of function type @var{fntype}, or if NULL of the current function. The +default is to return @code{TYPE_EMPTY_P(@var{type})}. +@end deftypefn + @deftypefn {Target Hook} void TARGET_WARN_PARAMETER_PASSING_ABI (cumulative_args_t @var{ca}, tree @var{type}) This target hook warns about the change in empty class parameter passing ABI. --- gcc/doc/tm.texi.in.jj 2020-03-12 09:35:05.432126619 +0100 +++ gcc/doc/tm.texi.in 2020-04-27 14:17:02.920795688 +0200 @@ -3490,6 +3490,8 @@ nothing when you use @option{-freg-struc @hook TARGET_EMPTY_RECORD_P +@hook TARGET_EMPTY_TYPE_P + @hook TARGET_WARN_PARAMETER_PASSING_ABI @node Caller Saves --- gcc/target.def.jj 2020-03-17 13:50:52.713936762 +0100 +++ gcc/target.def 2020-04-27 14:16:25.740356959 +0200 @@ -5225,6 +5225,15 @@ is to return @code{false}.", bool, (const_tree type), hook_bool_const_tree_false) +/* Return true if a type is an empty record in a particular ABI context. */ +DEFHOOK +(empty_type_p, + "This target hook returns true if the type is an empty record in the ABI\n\ +of function type @var{fntype}, or if NULL of the current function. The\n\ +default is to return @code{TYPE_EMPTY_P(@var{type})}.", + bool, (const_tree fndecl, const_tree type), + default_empty_type_p) + /* Warn about the change in empty class parameter passing ABI. */ DEFHOOK (warn_parameter_passing_abi, The remaining problem are (besides testing) that two last uses of TYPE_EMPTY_P in tree.c and one use in calls.c need to pass in information on the function type being called if it is on the caller side, or NULL on the callee side, and that means the function needs new argument, and associated target hook too etc. :( ^ permalink raw reply [flat|nested] 15+ messages in thread
* [Bug target/94770] class with empty base passed incorrectly with -std=c++17 on mingw 2020-04-26 9:17 [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw sbence92 at gmail dot com ` (12 preceding siblings ...) 2020-04-27 12:27 ` jakub at gcc dot gnu.org @ 2020-05-09 19:37 ` sbence92 at gmail dot com 13 siblings, 0 replies; 15+ messages in thread From: sbence92 at gmail dot com @ 2020-05-09 19:37 UTC (permalink / raw) To: gcc-bugs https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94770 --- Comment #14 from Bence Szabó <sbence92 at gmail dot com> --- (In reply to Jakub Jelinek from comment #13) > Completely untested WIP patch: Results with ead1c27a530 + this patch: The same tests fail as in the original description, t032 and t059 crash/pass the same way as described in comment 6. Also, running the testsuite (check-c++) shows new failed tests: FAIL: g++.dg/compat/abi/pr83487-1 cp_compat_x_tst.o-cp_compat_y_tst.o execute FAIL: g++.dg/compat/abi/pr83487-2 cp_compat_x_tst.o-cp_compat_y_tst.o execute FAIL: g++.dg/lookup/ns1.C -std=c++98 (test for excess errors) FAIL: g++.dg/torture/pr39417.C -O0 execution test FAIL: g++.old-deja/g++.robertl/eb21.C -std=c++14 execution test (timeout) FAIL: g++.old-deja/g++.robertl/eb21.C -std=c++17 execution test (timeout) FAIL: g++.old-deja/g++.robertl/eb21.C -std=c++2a execution test (timeout) ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2020-05-09 19:37 UTC | newest] Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-04-26 9:17 [Bug target/94770] New: class with empty base passed incorrectly with -std=c++17 on mingw sbence92 at gmail dot com 2020-04-26 15:15 ` [Bug target/94770] " jakub at gcc dot gnu.org 2020-04-26 20:44 ` sbence92 at gmail dot com 2020-04-26 20:45 ` sbence92 at gmail dot com 2020-04-26 21:26 ` sbence92 at gmail dot com 2020-04-26 21:28 ` jakub at gcc dot gnu.org 2020-04-27 7:50 ` sbence92 at gmail dot com 2020-04-27 9:51 ` jakub at gcc dot gnu.org 2020-04-27 10:49 ` redi at gcc dot gnu.org 2020-04-27 10:50 ` redi at gcc dot gnu.org 2020-04-27 11:04 ` jakub at gcc dot gnu.org 2020-04-27 11:41 ` jakub at gcc dot gnu.org 2020-04-27 11:48 ` jakub at gcc dot gnu.org 2020-04-27 12:27 ` jakub at gcc dot gnu.org 2020-05-09 19:37 ` sbence92 at gmail dot com
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).