177 lines
7.2 KiB
Diff
177 lines
7.2 KiB
Diff
From 2cca047791a52015d63fd42e9791ed7dc237099d Mon Sep 17 00:00:00 2001
|
|
From: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
|
|
Date: Fri, 22 Jun 2018 15:58:38 +0000
|
|
Subject: [PATCH] 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.
|
|
|
|
Backport from mainline
|
|
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.
|
|
|
|
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-7-branch@261907 138bc75d-0d04-0410-961f-82ee72b054a4
|
|
---
|
|
libstdc++-v3/ChangeLog | 16 ++++++++++
|
|
libstdc++-v3/include/bits/basic_string.tcc | 25 ++++++++++++++--
|
|
.../basic_string/cons/char/86138.cc | 30 +++++++++++++++++++
|
|
.../basic_string/cons/wchar_t/86138.cc | 30 +++++++++++++++++++
|
|
4 files changed, 98 insertions(+), 3 deletions(-)
|
|
create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/cons/char/86138.cc
|
|
create mode 100644 libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/86138.cc
|
|
|
|
diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc
|
|
index 41b7fa196b0..d185a54aaf0 100644
|
|
--- a/libstdc++-v3/include/bits/basic_string.tcc
|
|
+++ b/libstdc++-v3/include/bits/basic_string.tcc
|
|
@@ -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
|
|
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/86138.cc b/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/86138.cc
|
|
new file mode 100644
|
|
index 00000000000..a85fd9c82c9
|
|
--- /dev/null
|
|
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/86138.cc
|
|
@@ -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++1z } }
|
|
+// { 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();
|
|
+}
|
|
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/86138.cc b/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/86138.cc
|
|
new file mode 100644
|
|
index 00000000000..d77922976d0
|
|
--- /dev/null
|
|
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/86138.cc
|
|
@@ -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++1z } }
|
|
+// { 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();
|
|
+}
|
|
--
|
|
2.18.0
|
|
|