https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124263
Bug ID: 124263
Summary: [contracts] handle_contract_violation from
libstdc++exp not resolved on MinGW/PE-COFF
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: kachalenko.denis at gmail dot com
Target Milestone: ---
libstdc++exp.a provides a default weak handle_contract_violation in
contract26.o
(contract26.cc uses __attribute__((weak))). On MinGW/PE-COFF targets, this weak
definition does not resolve — the linker reports an undefined reference even
when linking -lstdc++exp or when contract26.o is linked directly.
--- mod.cppm ---
export module M;
import std;
export struct Box {
int D[4] = {};
constexpr int operator[](int I) const noexcept
pre(I >= 0 && I < 4)
{ return D[I]; }
};
--- main.cpp ---
import M;
import std;
int main() { Box b; std::cout << b[0]; }
--- commands ---
$ g++ -std=c++26 -fmodules -fcontracts -fcontract-evaluation-semantic=enforce \
-c <gcc-install>/include/c++/16.0.1/bits/std.cc
$ g++ -std=c++26 -fmodules -fcontracts -fcontract-evaluation-semantic=enforce \
-c mod.cppm -o mod.o
$ g++ -std=c++26 -fmodules -fcontracts -fcontract-evaluation-semantic=enforce \
-c main.cpp -o main.o
$ g++ mod.o main.o -o test.exe -lstdc++exp
--- expected ---
handle_contract_violation resolves from libstdc++exp.a (contract26.o provides
a weak default that calls __handle_contract_violation).
--- actual ---
ld: mod.o:mod.cppm:(.text+0x26): undefined reference to
`handle_contract_violation(std::contracts::contract_violation const&)'
collect2.exe: error: ld returned 1 exit status
Even extracting contract26.o from the archive and linking directly fails:
$ ar x libstdc++exp.a contract26.o
$ g++ mod.o main.o contract26.o -o test.exe
ld: undefined reference to `handle_contract_violation(...)'
--- analysis ---
nm --defined-only -g contract26.o shows no global definition of
handle_contract_violation:
0000 T
.weak._Z25handle_contract_violationRKNSt9contracts18contract_violationE._ZNKSt5ctypeIcE8do_widenEc
0000 T _Z27__handle_contract_violationRKNSt9contracts18contract_violationE
0000 T _ZNKSt5ctypeIcE8do_widenEc
0000 T
_ZNSt9contracts41invoke_default_contract_violation_handlerERKNS_18contract_violationE
nm contract26.o | grep handle_contract_violation:
w _Z25handle_contract_violationRKNSt9contracts18contract_violationE
The symbol appears as 'w' (weak undefined), not as a weak definition. The
.weak.X.Y section mechanism does not produce a resolvable symbol on PE-COFF.
A user-provided strong definition of handle_contract_violation works fine.
--- gcc -v ---
Using built-in specs.
Target: x86_64-w64-mingw32
Configured with: ../gcc-source/configure --prefix=/home/kacha/gcc-trunk-install
--build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32
--target=x86_64-w64-mingw32 --enable-languages=c,c++ --enable-threads=posix
--enable-shared --enable-static --enable-lto --enable-plugin
--enable-checking=release --disable-multilib --disable-nls --disable-werror
--disable-bootstrap --with-tune=native --with-system-zlib --with-zstd
--with-native-system-header-dir=/ucrt64/include
Thread model: posix
gcc version 16.0.1 20260221 (experimental) (GCC)
Linker: GNU ld (GNU Binutils) 2.46
Related to Bug 119061 (P2900 Contracts tracker).