Skip to content

Work around GCC miscompiling the provider lists - #730

Merged
arch1t3cht merged 1 commit into
TypesettingTools:masterfrom
CoffeeFlux:fix/gcc-provider-list-miscompile
Oct 9, 2026
Merged

arch1t3cht merged 1 commit into
TypesettingTools:masterfrom
CoffeeFlux:fix/gcc-provider-list-miscompile

Conversation

@CoffeeFlux

@CoffeeFlux CoffeeFlux commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Since #655 added the extensions vector to the audio and video provider factories, Linux builds of master made with GCC crash whenever they open audio or video. No release is affected, since #655 landed after 3.5.0, and the Windows (MSVC) and macOS (clang) builds are fine.

Cause

This is GCC bug 126472: when a namespace-scope std::initializer_list mixes elements that can be constant-initialized with ones that can't, the static initializer leaves the constant ones zeroed. In C++20, std::vector's default constructor is constexpr, so our Dummy entries (with an empty extensions list) are constant while the others, whose lists need a heap allocation, aren't. The Dummy entries therefore end up with a null name, and GetSorted crashes comparing the preferred provider's name against it.

Minimal reproducer:

#include <cstdio>
#include <initializer_list>
#include <vector>
struct factory { const char *name; std::vector<const char *> ext; };
const std::initializer_list<factory> list = {{"a", {}}, {"b", {"x"}}};
int main() { for (auto const& f : list) std::printf("%s ", f.name ? f.name : "(null)"); std::printf("\n"); }
Compiler Output
GCC 13.3, 14.2, 15.3, 16.2 (-std=c++20) (null) b
GCC 16.2 with -std=c++17 a b
GCC trunk snapshot (20260902), Apple clang a b

The GCC fix (126335) is on trunk and was backported for 16.3, but not to 15 or earlier, so e.g. Ubuntu 24.04's default GCC 13 (which our Linux CI uses) will keep miscompiling this.

Fix

Store both lists in a std::vector, which every compiler above initializes correctly, and leave a comment linking the GCC bug so they don't get turned back into initializer_lists.

Why CI didn't catch it

Master's Linux CI does build with the affected GCC 13.3, but none of its tests open audio or video: the gtest suite only links libaegisub, and the provider lists live in src/. It showed up in #670, whose end-to-end CLI tests are the first to load a video. There it crashed on every --video, including a missing file, and the tests pass in an Ubuntu 24.04 container (GCC 13.3) with this change. I haven't run the GUI from master on Linux, but the failing code runs during static initialization, before anything CLI-specific.

🤖 Generated with Claude Code

GCC miscompiles a namespace-scope std::initializer_list whose elements
are a mix of constant-initializable and non-constant ones: the static
initializer leaves the constant ones zeroed
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126472). Since TypesettingTools#655 added
the extensions vector, the Dummy entries of the audio and video provider
lists are such elements in C++20, where std::vector's default
constructor is constexpr. With an affected GCC (at least 13 through
16.2; fixed for 16.3), every attempt to open audio or video therefore
dereferences a null provider name and crashes.

A std::vector is initialized correctly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CoffeeFlux
CoffeeFlux force-pushed the fix/gcc-provider-list-miscompile branch from 39d33b8 to 8503fe3 Compare October 8, 2026 21:06
@arch1t3cht
arch1t3cht merged commit 4e440a6 into TypesettingTools:master Oct 9, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants