mirror of git://gcc.gnu.org/git/gcc.git
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. From-SVN: r261873
This commit is contained in:
parent
30043df975
commit
d72888d340
|
|
@ -1,3 +1,16 @@
|
|||
2018-06-22 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
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.
|
||||
|
||||
2018-06-21 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/83328
|
||||
|
|
|
|||
|
|
@ -1597,8 +1597,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
|
||||
// Inhibit implicit instantiations for required instantiations,
|
||||
// which are defined via explicit instantiations elsewhere.
|
||||
#if _GLIBCXX_EXTERN_TEMPLATE > 0 && __cplusplus <= 201402L
|
||||
#if _GLIBCXX_EXTERN_TEMPLATE > 0
|
||||
// The explicit instantiations definitions in src/c++11/string-inst.cc
|
||||
// are compiled as C++14, so the new C++17 members aren't instantiated.
|
||||
// Until those definitions are compiled as C++17 suppress the declaration,
|
||||
// so C++17 code will implicitly instantiate std::string and std::wstring
|
||||
// as needed.
|
||||
# if __cplusplus <= 201402L
|
||||
extern template class basic_string<char>;
|
||||
# elif ! _GLIBCXX_USE_CXX11_ABI
|
||||
// Still need to prevent implicit instantiation of the COW empty rep,
|
||||
// to ensure the definition in libstdc++.so is unique (PR 86138).
|
||||
extern template basic_string<char>::size_type
|
||||
basic_string<char>::_Rep::_S_empty_rep_storage[];
|
||||
# endif
|
||||
|
||||
extern template
|
||||
basic_istream<char>&
|
||||
operator>>(basic_istream<char>&, string&);
|
||||
|
|
@ -1613,7 +1626,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
getline(basic_istream<char>&, string&);
|
||||
|
||||
#ifdef _GLIBCXX_USE_WCHAR_T
|
||||
# if __cplusplus <= 201402L
|
||||
extern template class basic_string<wchar_t>;
|
||||
# elif ! _GLIBCXX_USE_CXX11_ABI
|
||||
extern template basic_string<wchar_t>::size_type
|
||||
basic_string<wchar_t>::_Rep::_S_empty_rep_storage[];
|
||||
# endif
|
||||
|
||||
extern template
|
||||
basic_istream<wchar_t>&
|
||||
operator>>(basic_istream<wchar_t>&, wstring&);
|
||||
|
|
@ -1626,8 +1645,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
extern template
|
||||
basic_istream<wchar_t>&
|
||||
getline(basic_istream<wchar_t>&, wstring&);
|
||||
#endif
|
||||
#endif
|
||||
#endif // _GLIBCXX_USE_WCHAR_T
|
||||
#endif // _GLIBCXX_EXTERN_TEMPLATE > 0
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do compile { target c++17 } }
|
||||
// { dg-final { scan-assembler-not "_ZNSs4_Rep20_S_empty_rep_storageE:" } }
|
||||
|
||||
#undef _GLIBCXX_USE_CXX11_ABI
|
||||
#define _GLIBCXX_USE_CXX11_ABI 0
|
||||
#include <string>
|
||||
|
||||
void
|
||||
test01(std::string* s)
|
||||
{
|
||||
s->~basic_string();
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (C) 2018 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do compile { target c++17 } }
|
||||
// { dg-final { scan-assembler-not "_ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE:" } }
|
||||
|
||||
#undef _GLIBCXX_USE_CXX11_ABI
|
||||
#define _GLIBCXX_USE_CXX11_ABI 0
|
||||
#include <string>
|
||||
|
||||
void
|
||||
test01(std::wstring* s)
|
||||
{
|
||||
s->~basic_string();
|
||||
}
|
||||
Loading…
Reference in New Issue