Created attachment 43483 [details] Minimal example Hi, we've discovered a strange problem when passing many function arguments where one argument is an alias (using = ...) for a templated struct which has no members (e.g. std::integer_sequence). When building in non-optimized mode or with -O1/-O2, all arguments starting from argument #7 seem to be corrupt. Building with -O3 seems to solve the issue. I've attached a small example program. Correct output: --------------- $ ~/gcc-8/bin/g++ -O3 -o repro repro.cpp && ./repro 0, 1, 2, 3, 4, 5, 6, 7 Wrong outputs: -------------- $ ~/gcc-8/bin/g++ -O2 -o repro repro.cpp && ./repro 0, 1, 2, 3, 4, 5, 7, 0 $ ~/gcc-8/bin/g++ -O1 -o repro repro.cpp && ./repro 0, 1, 2, 3, 4, 5, 7, 0 $ ~/gcc-8/bin/g++ -O0 -o repro repro.cpp && ./repro 0, 1, 2, 3, 4, 5, 7, 2088590376 gcc version (freshly built): ---------------------------- $ ~/gcc-8/bin/g++ -v Using built-in specs. COLLECT_GCC=/home/patrick/gcc-8/bin/g++ COLLECT_LTO_WRAPPER=/home/patrick/gcc-8/libexec/gcc/x86_64-pc-linux-gnu/8.0.1/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ./configure --prefix=/home/patrick/gcc-8 --disable-multilib Thread model: posix gcc version 8.0.1 20180218 (experimental) (GCC) Best Regards Patrick
Note: This problem does not happen with gcc 7.2.1. The problem can also be reproduced with -O3 when the empty struct object passed to the function is actually used in the function. (So it is not optimized out.)
This is caused by -fabi-version=12 (which is the default for GCC 8). You can get the old handling of empty structs with -fabi-version=11 The bug only seems to happen when the empty struct is a class template. Reduced, this fails at -O0 but not any other optimization level, or with -fabi-version=11: template<typename T> struct EmptyTemplatedStruct { }; using X = EmptyTemplatedStruct<int>; void func(X, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { if (a1 != 0) __builtin_abort(); if (a2 != 1) __builtin_abort(); if (a3 != 2) __builtin_abort(); if (a4 != 3) __builtin_abort(); if (a5 != 4) __builtin_abort(); if (a6 != 5) __builtin_abort(); if (a7 != 6) __builtin_abort(); if (a8 != 7) __builtin_abort(); } int main() { func(X{}, 0, 1, 2, 3, 4, 5, 6, 7); }
This might be the reason why building Chromium gn fails (I hope). Related: PR84286
Regressed with r255066
Completely untested fix: --- gcc/stor-layout.c.jj 2018-02-13 21:23:29.187981310 +0100 +++ gcc/stor-layout.c 2018-02-21 21:43:24.783522853 +0100 @@ -1883,6 +1883,9 @@ finalize_type_size (tree type) && TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST) TYPE_SIZE_UNIT (type) = variable_size (TYPE_SIZE_UNIT (type)); + /* Handle empty records as per the x86-64 psABI. */ + TYPE_EMPTY_P (type) = targetm.calls.empty_record_p (type); + /* Also layout any other variants of the type. */ if (TYPE_NEXT_VARIANT (type) || type != TYPE_MAIN_VARIANT (type)) @@ -1895,6 +1898,7 @@ finalize_type_size (tree type) unsigned int precision = TYPE_PRECISION (type); unsigned int user_align = TYPE_USER_ALIGN (type); machine_mode mode = TYPE_MODE (type); + bool empty_p = TYPE_EMPTY_P (type); /* Copy it into all variants. */ for (variant = TYPE_MAIN_VARIANT (type); @@ -1911,11 +1915,9 @@ finalize_type_size (tree type) SET_TYPE_ALIGN (variant, valign); TYPE_PRECISION (variant) = precision; SET_TYPE_MODE (variant, mode); + TYPE_EMPTY_P (variant) = empty_p; } } - - /* Handle empty records as per the x86-64 psABI. */ - TYPE_EMPTY_P (type) = targetm.calls.empty_record_p (type); } /* Return a new underlying object for a bitfield started with FIELD. */
(In reply to Jakub Jelinek from comment #5) > Completely untested fix: I've applied the patch and it seems to resolve the issue. Thanks a lot!
Author: jakub Date: Thu Feb 22 08:29:56 2018 New Revision: 257892 URL: https://gcc.gnu.org/viewcvs?rev=257892&root=gcc&view=rev Log: PR target/84502 * stor-layout.c (finalize_type_size): Propagate TYPE_EMPTY_P flag to all type variants. * g++.dg/torture/pr84502.C: New test. Added: trunk/gcc/testsuite/g++.dg/torture/pr84502.C Modified: trunk/gcc/ChangeLog trunk/gcc/stor-layout.c trunk/gcc/testsuite/ChangeLog
Fixed.