https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127126
Bug ID: 127126
Summary: [C++26] Wrong code: constexpr folding disagrees with
strict constant evaluation and runtime (-std=c++2c
only)
Product: gcc
Version: 16.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: jose93rd at gmail dot com
Target Milestone: ---
Created attachment 65444
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65444&action=edit
Single-file reproducer (standard headers only): constexpr-folded value
disagrees with static_assert and runtime under -std=c++2c; correct with
-std=c++23. Any -O level.
With -std=c++2c, GCC folds a constexpr call with literal arguments to a
DIFFERENT
result than both strict constant evaluation (constexpr context / static_assert)
and runtime execution of the same function. No diagnostic is emitted. The same
program behaves correctly with -std=c++23.
The function parses "12.34.56" into three uint32_t components using
std::string_view and returns std::expected<V, int>. Under -std=c++2c the folded
call returns unexpected(2) — the branch for "character is not a digit" — i.e.
during folding the comparison (ch < '0' || ch > '9') apparently misjudges a
digit. Strict constant evaluation of the identical call (static_assert) passes,
and the runtime call (folding defeated via a volatile pointer) is also correct.
$ g++ --version | head -1
g++ (GCC) 16.2.1 20260810
$ g++ -std=c++2c -O0 gcc-repro-diag.cpp -o r && ./r
folded: ERROR code=2
runtime: ok {12.34.56}
$ g++ -std=c++23 -O0 gcc-repro-diag.cpp -o r && ./r
folded: ok {12.34.56}
runtime: ok {12.34.56}
Notes:
- Independent of optimization level: identical results at -O0, -O1 and -O2, so
the defect appears to live in the constant evaluator used for folding under
the C++26 language mode, not in the optimizer.
- Strict constant evaluation is CORRECT in both modes; only the
non-manifestly-constant-evaluated folding path diverges, which makes this
silent wrong-code (no error, no warning, no sanitizer finding).
- Reduced from a production codebase; the attached reproducer is self-contained
(only <cstdint>, <cstdio>, <expected>, <string_view>).
- Target: x86_64-pc-linux-gnu (Arch Linux).