Repository navigation
Quiet gcc's ASan -Wmaybe-uninitialized false positives in expected<void, E> - #104
Merged
steve-downey merged 2 commits intoOct 19, 2026
Merged
Conversation
… under ASan
Under -fsanitize=address, the use-after-scope markers stop gcc forwarding a
just-stored has_val_ to the load that guards the read of unex_, so a
value-state expected<void, E> whose union was never written gets that read
reported as -Wmaybe-uninitialized. Every instance is a false positive; the
guard is exact. It accounted for 43 of the 44 warnings in the default Asan
build with gcc 15.
Add an empty `struct {} void_;` alternative to the union and initialize it in
every constructor that can end in the value state, as libstdc++'s
expected<void, E> does. The front end folds the constructor to an aggregate,
and because an empty member does not fill the union the gimplifier zero-clears
the whole object before storing the fields, so nothing is left unwritten.
The member is unmarked, so specgen drops it from the synopsis; the generated
wording is unchanged. The explanation lives after the class body because a
comment inside the union is carried into the synopsis.
The gcc-14, gcc-15 and gcc-16 toolchain files each appended -Wno-maybe-uninitialized to the Asan flags; the default toolchain.cmake and gcc-12/13 did not, so a plain `make` warned 44 times where `make TOOLCHAIN=gcc-16` was clean. The suppression is not version-gated, so it belongs in gcc-flags.cmake. It is still needed after expected<void, E> was fixed at the source: expected<T&, E>'s value constructor stores a runtime address, so the same folding cannot apply, and its copy constructor with a non-trivial E still trips the false positive.
This was referenced Oct 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
gcc's
-fsanitize=addressbuild reports-Wmaybe-uninitializedon reads ofunex_in value-stateexpected<void, E>objects. Every report is a false positive, sincehas_val_guards each read exactly. They were 43 of the 44 warnings in the default Asan build with gcc 15.struct {} void_;alternative and initialize it in every constructor that can end in the value state, as libstdc++'sexpected<void, E>does. The member is unmarked, so specgen leaves it out of the synopsis. Its rationale sits after the class body, because a comment inside the union would be carried into the synopsis.-Wno-maybe-uninitializedto the Asan flags, but the default toolchain and gcc-12/13 did not. A plainmakewarned 44 times wheremake TOOLCHAIN=gcc-16was clean. The suppression isn't version-gated, so it now lives ingcc-flags.cmake. It's still needed forexpected<T&, E>, whose value constructor stores a runtime address, so the same folding can't apply.gcc-16: 1249/1249 tests pass.
The generated wording is unchanged. I checked that by regenerating it with specgen 0.4.0 on top of this branch. Earlier specgen releases could leak
void_;into theexpected<void, E>synopsis once this member sat beside the\omitted copy assignment from #100 (steve-downey/specgen#147), so regenerate with 0.4.0 or later.