Compiler Bug Causes Compiler Bug: How a 12-Year-Old G++ Bug Took Down Solidity

https://news.ycombinator.com/rss Hits: 3
Summary

Compilers aren't supposed to crash — especially not when compiling perfectly valid code like this: // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.25; contract A { function a () public pure returns ( uint256 ) { return 1 ** 2 ; } } Yet running Solidity's compiler (solc) on this file on a standard Ubuntu 22.04 system (G++ 11.4, Boost 1.74) causes an immediate segmentation fault. At first, this seemed absurd. The code just returns 1 to the power of 2 — no memory tricks, unsafe casting, or undefined behavior. And yet, it crashes. Another minimal example? // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.25; contract A { function a () public pure { uint256 [ 1 ] data; } } Still crashes. So what’s going on? We traced it down to a seemingly unrelated C++ line deep in the compiler backend: if ( * lengthValue == 0 ) { ... } That single comparison — a boost::rational compared to 0 — causes infinite recursion in G++ < 14 when compiled under C++20. And the resulting stack overflow crashes solc. This post unpacks how this happened — and why none of the individual components are technically "broken": A 12-year-old overload resolution bug in G++ An outdated symmetric comparison pattern in Boost A subtle but impactful rewrite rule in C++20 Put together, they form a perfect storm — one that takes down Solidity compilation on default Linux setups, even though your code is perfectly fine. If you follow the Solidity build documentation (v0.8.30), you'll see it recommends: Boost ≥ 1.67 GCC ≥ 11 Ubuntu 22.04, for example, ships with: G++ 11.4.0 Boost 1.74.0 So far, so good. However, Solidity enabled C++20 in January 2025: This wasn't accompanied by an update to the versions of dependencies in the documentation. As we'll soon see, that's what opened the trapdoor. In C++, when you write an expression like a == b , the compiler chooses among available operator== implementations by comparing their match quality. A member function like a.operator==(b) usually has higher...

First seen: 2025-08-15 16:22

Last seen: 2025-08-15 18:22