Crashing GCC with 63 Bytes
2020-10-15, post № 235
C++, error, #GCC, #g++, #internal compiler error
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 [1], 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 machine defined by the standard.
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 [2]. 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 constant 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 implementation 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 implementation. Unsuspectingly typing away at my keyboard, I was shocked to receive a compilation error of a type which I have never encountered before:
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 [4].
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 standard:
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 regarding its crash, I set out to create a Bugzilla account and filed a bug report: Bug 97430.
Hopefully this compiler bug soon gets fixed [5] 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 experience.
Footnotes
- ▲ See https://
github.com/ jfrech/ joy-assembler. - ▲ See Joy-Assember@fee15a4/Types.hpp#L118 for the full source code context.
- ▲
internal compiler error: in verify_ctor_sanity, at
cp/constexpr.c:3884
- ▲ To browse the repository at this point in time, see Joy-Assembler@e0bf0f1.
- ▲ [2020-10-28] My bug report has been marked to be a duplicate of Bug 96241, which in turn alledgedly has been fixed.