https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96934
Bug ID: 96934 Summary: Copy initialization of struct involving aggregate array initialization miscompiles in GCC 9 Product: gcc Version: 9.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: wielkiegie at gmail dot com Target Milestone: --- GCC 9 (but not <= 8 and not >= 10, including trunk) miscompiles the following piece of code. I have tested GCC 9.1 (which produces even worse code, as it assumes the const char* has only a single character) and GCC 9.2, 9.3 (explained below). I was not able to test the current GCC 9 branch. Test case: https://godbolt.org/z/jPq4h7 The Code struct holds an array of chars that is meant to be always null-terminated. A simple constructor is provided to simulate how the array should be initialized (this is a reduced real world scenario). It uses aggregate initialization in order to store the "12" string. There are two problems, probably originating from the same underlying issue: 1. Bogus -Wstringop-overflow warning saying the _buffer is unterminated, while it most certainly is (as you can see in the assembly). 2. std::strcmp call miscompiled as if _buffer == "1" (and not "12"). Switching the TEST define on line 17 into T1, T2, T3, T4 doesn't change the outcome. However, T5 and T6 fix the issue. What seems to be the difference is the copy-initialization [1] being involved in T1 and T2 (and T3, T4 "inheriting" the buggy state). T5 doesn't do copy-initialization, and T6 just copies it. [1] https://en.cppreference.com/w/cpp/language/copy_initialization