https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90611
--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Aaron Greig from comment #0) > Created attachment 46403 [details] > cpp file that triggers the bug > > I am finding that when I compile the attached file, with the following > command: > g++-8 -m32 -std=c++11 -msse -O3 repro.cpp -o repro -Wall -Wextra > -fno-strict-aliasing -fwrapv > I get this output: > repro.cpp: In function ‘int main(int, char**)’: > repro.cpp:13:14: warning: unused parameter ‘argc’ [-Wunused-parameter] > int main(int argc, char** argv) { > ~~~~^~~~ > repro.cpp:13:27: warning: unused parameter ‘argv’ [-Wunused-parameter] > int main(int argc, char** argv) { > ~~~~~~~^~~~ You know you can just declare int main() or int main(int, char**) to have a reproducer that doesn't give any warnings, right? > and when I run the resulting binary on a 32-bit system I get an immediate > segfault. This seems to be due to a movaps instruction generating a general > protection exception (see https://www.felixcloutier.com/x86/movaps) because > the address it is loading from isn't aligned to 16 bytes. The minimal > command I have found to reproduce this is > g++-8 -m32 -std=c++11 -msse -O3 repro.cpp -o repro > the output of g++-8 --version is: > g++-8 (Ubuntu 8.3.0-6ubuntu1~18.04) 8.3.0 > The system I run the binary on is a virtualbox VM with 32-bit Ubuntu 16.04 > installed on it. I can reproduce this bug in the same way by compiling with > that system's installed g++, version: > g++ (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609 There are a few issues interacting here. 1) Glibc now (since version 2.26) returns 16-byte aligned memory from malloc, so this Just Works with a newer glibc. But if your code needed more than 16-byte alignment it would still fail even with a newer glibc, so let's assume you needed 32-byte alignment... 2) In C++11 and C++14 the standard library does not support overaligned types, it only supports the alignments that malloc supports. But C++17 added extended alignment support to the standard library, so compiling with -std=c++17 or -std=gnu++17 should make extended alignments work. You can also enable extended alignment support for C++11 and C++14 with the -faligned-new flag. However ... 3) GCC assumes glibc malloc always returns 16-byte aligned memory, even if you have glibc 2.25 or older, which only returns 8-byte alignment for x86. That means GCC thinks 16-byte is not extended, but malloc disagrees. I'm trying to fix that, see PR 90569. 4) To workaround PR 90569 you can use the -faligned-new=8 which tells GCC that any alignment higher than 8 should be considered an extended alignment, and so needs special handling (which means it doesn't use malloc, so isn't affected by old versions of malloc only returning 8-byte alignment). In summary: With a new glibc and C++17 extended alignments just work automatically. For older glibc and/or C++11 you can use -faligned-new=8 to make it work. I think there is no GCC bug here (except for PR 90569 which I'm already working on).