PR libstdc++/86138 prevent implicit instantiation of COW empty rep
commitab127dab999f4a03cab309884d9c432a5d2a9c83
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 21 Jun 2018 23:29:01 +0000 (21 23:29 +0000)
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 21 Jun 2018 23:29:01 +0000 (21 23:29 +0000)
treeb54e140f3bbafe1a72a08e90f288cf737ab07ded
parent4f96c7da9e1a12ce0af99bb78d6392095d56e3c8
PR libstdc++/86138 prevent implicit instantiation of COW empty rep

The explicit instantiation declarations for std::basic_string are
disabled for C++17 (and later) so that basic_string symbols get
implicitly instantiated in every translation unit that needs them.  On
targets that don't support STB_GNU_UNIQUE this leads to multiple copies
of the empty rep symbol for COW strings. In order to detect whether a
COW string needs to deallocate its storage it compares the address with
the empty rep.  When there are multiple copies of the empty rep object
the address is not unique, and so string destructors try to delete the
empty rep, which crashes.

In order to guarantee uniqueness of the _S_empty_rep_storage symbol this
patch adds an explicit instantiation declaration for just that symbol.
This means the other symbols are still implicitly instantiated in C++17
code, but for the empty rep the definition in the library gets used.

Separately, there is no need for C++17 code to implicitly instantiate
the I/O functions for strings, so this also restores the explicit
instantiation declarations for those functions.

PR libstdc++/86138
* include/bits/basic_string.tcc:
[__cplusplus > 201402 && !_GLIBCXX_USE_CXX11_ABI]
(basic_string<char>::_Rep::_S_empty_rep_storage)
(basic_string<wchar_t>::_Rep::_S_empty_rep_storage): Add explicit
instantiation declarations.
[__cplusplus > 201402] (operator>>, operator<<, getline): Re-enable
explicit instantiation declarations.
* testsuite/21_strings/basic_string/cons/char/86138.cc: New.
* testsuite/21_strings/basic_string/cons/wchar_t/86138.cc: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@261873 138bc75d-0d04-0410-961f-82ee72b054a4
libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/basic_string.tcc
libstdc++-v3/testsuite/21_strings/basic_string/cons/char/86138.cc [new file with mode: 0644]
libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/86138.cc [new file with mode: 0644]