This repository was archived by the owner on Apr 26, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpr86138.patch
176 lines (165 loc) · 7.16 KB
/
pr86138.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
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 <[email protected]>
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