https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93050
Bug ID: 93050 Summary: throw within constructor initialisation list causes invalid free in destructor Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: db0451 at gmail dot com Target Milestone: --- I've come across this error at least twice when trying to throw from constructor initialisation lists, so I don't *think* I'm uniquely at fault here... All I want to do is move/copy an argument into a member if suitable, and throw if not, while not having to use the constructor body, instead the ctor init-list The below code, compiled with... * g++ --version: `g++.exe (Rev2, Built by MSYS2 project) 9.2.0` * compiler args: `g++ -std=c++17 -Wall -Wextra -Wpedantic test.cpp` ...correctly throws when Test() is called with an empty string, but with a non-empty string is crashes in free() via ~Test(). source: ```cpp #include <stdexcept> #include <string> struct Test final { std::string m_string; Test(std::string string) : m_string{ !string.empty() ? std::move(string) : throw std::invalid_argument{"string cannot be empty"} } {} }; auto main() -> int { auto test = Test{"2"}; return 0; } ``` gdb log, run on ``` Reading symbols from ./a.exe...done. (gdb) run Starting program: /tmp/Atm/build/a.exe [New Thread 3880.0x3c38] [New Thread 3880.0x2b68] [New Thread 3880.0x5624] [New Thread 3880.0x4a14] warning: Critical error detected c0000374 Thread 1 received signal SIGTRAP, Trace/breakpoint trap. 0x00007ffdca4391f3 in ntdll!RtlIsNonEmptyDirectoryReparsePointAllowed () from /c/WINDOWS/SYSTEM32/ntdll.dll (gdb) bt #0 0x00007ffdca4391f3 in ntdll!RtlIsNonEmptyDirectoryReparsePointAllowed () from /c/WINDOWS/SYSTEM32/ntdll.dll #1 0x00007ffdca441622 in ntdll!RtlpNtMakeTemporaryKey () from /c/WINDOWS/SYSTEM32/ntdll.dll #2 0x00007ffdca44192a in ntdll!RtlpNtMakeTemporaryKey () from /c/WINDOWS/SYSTEM32/ntdll.dll #3 0x00007ffdca44a8e9 in ntdll!RtlpNtMakeTemporaryKey () from /c/WINDOWS/SYSTEM32/ntdll.dll #4 0x00007ffdca38088d in ntdll!RtlGetCurrentServiceSessionId () from /c/WINDOWS/SYSTEM32/ntdll.dll #5 0x00007ffdca37fc11 in ntdll!RtlFreeHeap () from /c/WINDOWS/SYSTEM32/ntdll.dll #6 0x00007ffdc8fd9cfc in msvcrt!free () from /c/WINDOWS/System32/msvcrt.dll #7 0x0000000000402ef8 in Test::~Test() () #8 0x00000000004015d2 in main () (gdb) ``` Copying instead of `std::move()`ing the `string` doesn't seem to change anything Moving the check/throw into the constructor body works but shouldn't be needed.