Jonathan Frech’s Weblog

Crashing GCC with 63 Bytes#235

Jonathan Frech

Enthusiastically following C++20’s new compile-time capabilities as well as awaiting more powerful ones being promised in upcoming standards, yet being stuck on C++17¹, I try to take full advantage of the limited C++17-constexpr features. However, without static storage promotion, a constexpr std::string is all but a pipe dream, thereby necessitating the use of a wrapped static pointer; std::string_view.

One does not program against one’s compiler; one programs against the abstract ma­chine defined by the stan­dard.

-=-

As such, whilst I was refactoring away under the comforting veil of passing tests, a tear announced itself in form of an email containing an erroneous make compilation output². Excerpt (slightly formatted):

error: 'constexpr InstructionDefinitionsUtil::InstructionDefinitionsArray
        InstructionDefinitionsUtil::build()' called in constant expression

As unintuitive it may seem, I did indeed intend to call a constexpr builder inside a con­stant context, since I wanted to force compile-time computation of a lookup table. Alas, without C++20’s consteval specifier, a constexpr routine is only able to be evaluated at compile time, yet also leads to a dynamically accessible manifestation of its body.
Although I do not fully understand why, copying a std::string_view in a constexpr context seems to be the culprit. A culprit which is only detected by some GCC versions.

It turns out that there were two different compilers at play: I only tested my im­ple­men­ta­tion using g++ 9.3.0 and clang 10.0.0, not g++ 10.2.0, as was the aforementioned email’s author.
Thus, to ensure compilability even with newer versions of GCC, I updated my compiler to g++ 10.2.0 and began to correct my im­ple­men­ta­tion. Unsuspectingly typing away at my keyboard, I was shocked to receive a compilation error of a type which I have never encountered before:

internal compiler error³

Curious about the root cause, I set out to distill a minimal (non-)working example. After all, I encountered an internal compiler error in a project spanning multiple thousand lines of code.

A few hours later, I managed to write a 63 byte long C++ source file which crashes g++ 10.2.0 when compiling using the C++17 stan­dard:

int main(){[](){enum E{F};struct{E e{F};}p[1]{};return p->e;};}

Since the example is only a single short line, one can write a zsh one-liner to demonstrate GCC crashing:

% g++ -xc++ -std=c++17 =(printf 'int main(){[](){enum E{F};struct{E e{F};}p[1]{};return p->e;};}')

As my compiler asked kindly to file a report re­gard­ing its crash, I set out to create a Bugzilla account and filed a bug report: Bug 97430.

Hopefully this compiler bug soon gets fixed and C++20 is adopted swiftly, since being ping-ponged between unexpected constexpr compiler inabilities and seemingly arbitrary compiler crashes made for a rather unpleasant coding ex­pe­ri­ence.


[1]See https://github.com/jfrech/joy-assembler.
[2]See Joy-Assember@fee15a4/Types.hpp#L118 for the full source code context.
[3]internal compiler error: in verify_ctor_sanity, at cp/constexpr.c:3884
[4]To browse the repository at this point in time, see Joy-Assembler@e0bf0f1.
[5][2020-10-28] My bug report has been marked to be a duplicate of Bug 96241, which in turn alledgedly has been fixed.