https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86138
--- Comment #6 from Christian Franke <franke at computer dot org> ---
(In reply to Jonathan Wakely from comment #4)
> Could you please debug this to find where it's crashing and why?
It segfaults with a bogus pointer below std::string::_Rep::_M_dispose().
A comparison of assembly output and object file symbols leads to the root of
the problem:
1) -std=c++14: string::string() and getline() are called from cygstdc++6.dll.
OK.
2) -std=c++17: getline() is called from cygstdc++6.dll. All code for
string::string() is part of the executable. The empty string is initialized
with the static std::string::_Rep::_S_empty_rep_storage[] from the executable.
But getline() uses the string() implementation from the DLL which checks
against the DLL version of _S_empty_rep_storage[] here:
_M_dispose(const _Alloc& __a) _GLIBCXX_NOEXCEPT
{
#if _GLIBCXX_FULLY_DYNAMIC_STRING == 0
if (__builtin_expect(this != &_S_empty_rep(), false))
#endif
{ ... }
This finally results in a bogus delete[] of the _S_empty_rep_storage[] from the
executable.
2) -std=c++17 -static: The linker does not pull another _S_empty_rep_storage[]
from the static library because it already exists in the object file. OK.
This version of the testcase does not crash because _S_empty_rep_storage[] is
not used:
int main()
{
std::string line("x");
std::istringstream stream("*");
std::getline(stream, line, '\n');
return (int)line.c_str()[0];
}