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).

Reply via email to