https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127940
Bug ID: 127940
Summary: [modules] Optional bits/stdc++.h lookup rejects valid
replacement standard headers
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: joker.eph at gmail dot com
Target Milestone: ---
This is an issue we hit when testing LLVM libc++ with gcc 16, but it reproduces
with gcc 17 as well.
Below is a AI-generated summary of the investigation to reduce the CI issue to
a minimal reproducer. We have to disable module scanning with gcc in our CI in
the meantime.
## Summary
With modules enabled, GCC tries to translate an include of an importable
standard library header into an import of the libstdc++ `bits/stdc++.h`
header unit. If the original header exists but `bits/stdc++.h` is absent
from the include search path, this optional lookup produces a fatal error.
This breaks building libc++abi against libc++ headers with CMake's automatic
module dependency scanning. It also reproduces with an empty replacement
standard header, without any LLVM sources, compiled modules, or module cache.
## Minimal reproducer
Run in a fresh directory:
```sh
mkdir include
touch include/stdexcept
printf '#include <stdexcept>\n' > test.cc
# Control: succeeds.
g++ -std=c++23 -nostdinc++ -Iinclude -E test.cc -o plain.ii
# Fails despite include/stdexcept existing.
g++ -std=c++23 -nostdinc++ -Iinclude -fmodules-ts -E test.cc -o modules.ii
```
Actual diagnostic:
```text
test.cc:1:10: fatal error: bits/stdc++.h: No such file or directory
1 | #include <stdexcept>
| ^~~~~~~~~~~
compilation terminated.
```
The empty `include/stdexcept` is intentional: it isolates the compiler's
include translation from the contents of either standard library.
The equivalent dependency scan also fails:
```sh
g++ -std=c++23 -nostdinc++ -Iinclude -fmodules-ts \
-E -MD -MF test.d \
-fdeps-format=p1689r5 -fdeps-file=test.ddi -fdeps-target=test.o \
test.cc -o scan.ii
```
Expected: process the existing `include/stdexcept` textually when the
alternative header unit is unavailable. Merely enabling modules or scanning
should not require a libstdc++ header when using replacement standard headers.
## Suspected cause
The relevant behavior was introduced by
[GCC commit
9783f6f2f67f](https://github.com/gcc-mirror/gcc/commit/9783f6f2f67f9472fa428b984e4e045ee7b64f78),
`c++/modules: #include <vector> -> import <bits/stdc++.h>`.
The regression attribution is based on source inspection; it has not been
confirmed by building and bisecting GCC revisions.
In `gcc/cp/module.cc`, `maybe_translate_include` suggests `bits/stdc++.h` as
an alternative for importable standard headers. In `libcpp/files.cc`,
`_cpp_stack_include` looks up this alternative with `_cpp_FFK_NORMAL`.
That diagnoses a missing file even though this is only a speculative lookup
and the original header can still be processed textually.