https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124309
Bug ID: 124309
Summary: [modules] "Bad import dependency" when partition and
primary interface share a transitive import
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: kachalenko.denis at gmail dot com
Target Milestone: ---
When module B has a partition that imports C, and B's primary interface
imports A (which also imports C), importing B fails with
"Bad import dependency". The .gcm is written but cannot be read.
The dependency graph is a valid diamond — no cycles:
C
/ \
A B:Part
\ |
B (import A; export import :Part;)
|
consumer → ERROR
Per [module.import], a module can be imported any number of times and
through any number of paths. The compiler must deduplicate.
$ g++ -v
gcc version 16.0.1 20260221 (experimental) (GCC)
Target: x86_64-w64-mingw32
Thread model: posix
Configured with: [...] --enable-languages=c,c++
$ cat c.cppm
export module C;
$ cat a.cppm
export module A;
import C;
$ cat b-part.cppm
export module B:Part;
import C;
$ cat b.cppm
export module B;
import A;
export import :Part;
$ cat main.cpp
import B;
int main() {}
$ g++ -std=c++20 -fmodules -c c.cppm
$ g++ -std=c++20 -fmodules -c a.cppm
$ g++ -std=c++20 -fmodules -c b-part.cppm
$ g++ -std=c++20 -fmodules -c b.cppm
$ g++ -std=c++20 -fmodules -c main.cpp
In module imported at main.cpp:1:1:
B: error: failed to read compiled module: Bad import dependency
B: note: compiled module file is 'gcm.cache/B.gcm'
B: fatal error: returning to the gate for a mechanical issue
compilation terminated.
b.cppm compiles and B.gcm is written. The error occurs only when
reading B.gcm back. Inspecting B.gcm shows it records both
"import: C" and "import: A" plus "export: B:Part". B-Part.gcm
also records "import: C". The dependency check on C fails when
loading the partition because C was already loaded as a direct
import of B.
All three conditions are required (removing any one fixes the bug):
1. A imports C
2. B:Part imports C
3. B's primary imports A
Reproduces with -std=c++20 / -std=c++23 / -std=c++26.
Module C can be completely empty. Mapper has no effect.