Skip to content

Commit cb4f529

Browse files
committed
We need to always allocate debug proxies
1 parent 2c99992 commit cb4f529

File tree

1 file changed

+95
-81
lines changed

1 file changed

+95
-81
lines changed

stl/inc/xmemory

Lines changed: 95 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,9 +1160,8 @@ struct _Iterator_base0 {
11601160
// CLASS _Container_proxy
11611161
struct _Container_base12;
11621162
struct _Container_proxy { // store head of iterator chain and back pointer
1163-
_CONSTEXPR20_DYNALLOC _Container_proxy() noexcept : _Mycont(nullptr), _Myfirstiter(nullptr) {}
1164-
_CONSTEXPR20_DYNALLOC _Container_proxy(_Container_base12* _Mycont_) noexcept
1165-
: _Mycont(_Mycont_), _Myfirstiter(nullptr) {}
1163+
_CONSTEXPR20 _Container_proxy() noexcept : _Mycont(nullptr), _Myfirstiter(nullptr) {}
1164+
_CONSTEXPR20 _Container_proxy(_Container_base12* _Mycont_) noexcept : _Mycont(_Mycont_), _Myfirstiter(nullptr) {}
11661165

11671166
const _Container_base12* _Mycont;
11681167
_Iterator_base12* _Myfirstiter;
@@ -1198,8 +1197,10 @@ public:
11981197
_Container_proxy* _Myproxy;
11991198

12001199
private:
1201-
inline void _Orphan_all_impl() noexcept;
1202-
inline void _Swap_proxy_and_iterators_impl(_Container_base12&) noexcept;
1200+
_CONSTEXPR20_DYNALLOC void _Orphan_all_unlocked() noexcept;
1201+
inline void _Orphan_all_locked() noexcept;
1202+
_CONSTEXPR20_DYNALLOC void _Swap_proxy_and_iterators_unlocked(_Container_base12&) noexcept;
1203+
inline void _Swap_proxy_and_iterators_locked(_Container_base12&) noexcept;
12031204
};
12041205

12051206
struct _Iterator_base12 { // store links to container proxy, next iterator
@@ -1212,75 +1213,91 @@ struct _Iterator_base12 { // store links to container proxy, next iterator
12121213
}
12131214

12141215
_CONSTEXPR20_DYNALLOC _Iterator_base12& operator=(const _Iterator_base12& _Right) noexcept {
1215-
#ifdef __cpp_lib_is_constant_evaluated
1216-
if (!_STD is_constant_evaluated())
1217-
#endif // __cpp_lib_is_constant_evaluated
1218-
{
1219-
if (_Myproxy != _Right._Myproxy) {
1220-
if (_Right._Myproxy) {
1221-
_Adopt(_Right._Myproxy->_Mycont);
1222-
} else { // becoming invalid, disown current parent
1216+
if (_Myproxy != _Right._Myproxy) {
1217+
if (_Right._Myproxy) {
1218+
_Adopt(_Right._Myproxy->_Mycont);
1219+
} else { // becoming invalid, disown current parent
12231220
#if _ITERATOR_DEBUG_LEVEL == 2
1224-
_Orphan_me();
1221+
_Orphan_me();
12251222
#else // _ITERATOR_DEBUG_LEVEL == 2
1226-
_Myproxy = nullptr;
1223+
_Myproxy = nullptr;
12271224
#endif // _ITERATOR_DEBUG_LEVEL == 2
1228-
}
12291225
}
12301226
}
12311227
return *this;
12321228
}
12331229

12341230
#if _ITERATOR_DEBUG_LEVEL == 2
12351231
_CONSTEXPR20_DYNALLOC ~_Iterator_base12() noexcept {
1236-
#ifdef __cpp_lib_is_constant_evaluated
1237-
if (!_STD is_constant_evaluated())
1238-
#endif // __cpp_lib_is_constant_evaluated
1239-
{
1240-
_Orphan_me();
1241-
}
1242-
#if _HAS_CXX20 && defined(__clang__) // TRANSITION: LLVM-XXXX
1243-
else {
1244-
[[maybe_unused]] volatile auto _Guard = _Myproxy;
1232+
_Orphan_me();
1233+
}
1234+
1235+
_CONSTEXPR20_DYNALLOC void _Adopt_unlocked(_Container_proxy* _Parent_proxy) noexcept {
1236+
if (_Myproxy) { // adopted, remove self from list
1237+
_Orphan_me_unlocked();
12451238
}
1246-
#endif // _HAS_CXX20 && defined(__clang__)
1239+
_Mynextiter = _Parent_proxy->_Myfirstiter;
1240+
_Parent_proxy->_Myfirstiter = this;
1241+
_Myproxy = _Parent_proxy;
12471242
}
1248-
#endif // _ITERATOR_DEBUG_LEVEL == 2
12491243

1250-
#if _ITERATOR_DEBUG_LEVEL == 2
1251-
void _Adopt_impl(const _Container_base12* _Parent) noexcept {
1252-
if (_Parent) {
1253-
// have a parent, do adoption
1244+
void _Adopt_locked(_Container_proxy* _Parent_proxy) noexcept {
1245+
_Lockit _Lock(_LOCK_DEBUG);
1246+
_Adopt_unlocked(_Parent_proxy);
1247+
}
1248+
1249+
_CONSTEXPR20_DYNALLOC void _Adopt(const _Container_base12* _Parent) noexcept {
1250+
if (_Parent) { // have a parent, do adoption
12541251
_Container_proxy* _Parent_proxy = _Parent->_Myproxy;
12551252
if (_Myproxy != _Parent_proxy) { // change parentage
1256-
_Orphan_me();
1257-
_Lockit _Lock(_LOCK_DEBUG);
1258-
_Mynextiter = _Parent_proxy->_Myfirstiter;
1259-
_Parent_proxy->_Myfirstiter = this;
1260-
_Myproxy = _Parent_proxy;
1253+
#ifdef __cpp_lib_is_constant_evaluated
1254+
if (_STD is_constant_evaluated()) {
1255+
_Adopt_unlocked(_Parent_proxy);
1256+
} else
1257+
#endif // __cpp_lib_is_constant_evaluated
1258+
{
1259+
_Adopt_locked(_Parent_proxy);
1260+
}
12611261
}
1262-
} else {
1263-
// no future parent, just disown current parent
1262+
} else { // no future parent, just disown current parent
12641263
_Orphan_me();
12651264
}
12661265
}
12671266

1268-
_CONSTEXPR20_DYNALLOC void _Adopt(const _Container_base12* _Parent) noexcept {
1267+
_CONSTEXPR20_DYNALLOC void _Orphan_me_unlocked() noexcept {
1268+
_Iterator_base12** _Pnext = &_Myproxy->_Myfirstiter;
1269+
while (*_Pnext && *_Pnext != this) {
1270+
_Pnext = &(*_Pnext)->_Mynextiter;
1271+
}
1272+
1273+
_STL_VERIFY(*_Pnext, "ITERATOR LIST CORRUPTED!");
1274+
*_Pnext = _Mynextiter;
1275+
_Myproxy = nullptr;
1276+
}
1277+
1278+
void _Orphan_me_locked() noexcept {
1279+
_Lockit _Lock(_LOCK_DEBUG);
1280+
_Orphan_me_unlocked();
1281+
}
1282+
1283+
_CONSTEXPR20_DYNALLOC void _Orphan_me() noexcept {
1284+
if (_Myproxy) { // adopted, remove self from list
12691285
#ifdef __cpp_lib_is_constant_evaluated
1270-
if (!_STD is_constant_evaluated())
1286+
if (_STD is_constant_evaluated()) {
1287+
_Orphan_me_unlocked();
1288+
} else
12711289
#endif // __cpp_lib_is_constant_evaluated
1272-
{
1273-
_Adopt_impl(_Parent);
1290+
{
1291+
_Orphan_me_locked();
1292+
}
12741293
}
12751294
}
1295+
12761296
#else // ^^^ _ITERATOR_DEBUG_LEVEL == 2 ^^^ / vvv _ITERATOR_DEBUG_LEVEL != 2 vvv
12771297
_CONSTEXPR20_DYNALLOC void _Adopt(const _Container_base12* _Parent) noexcept {
1278-
if (_Parent) {
1279-
// have a parent, do adoption
1280-
_Container_proxy* _Parent_proxy = _Parent->_Myproxy;
1281-
_Myproxy = _Parent_proxy;
1282-
} else {
1283-
// no future parent, just disown current parent
1298+
if (_Parent) { // have a parent, do adoption
1299+
_Myproxy = _Parent->_Myproxy;
1300+
} else { // no future parent, just disown current parent
12841301
_Myproxy = nullptr;
12851302
}
12861303
}
@@ -1290,55 +1307,41 @@ struct _Iterator_base12 { // store links to container proxy, next iterator
12901307
return _Myproxy ? _Myproxy->_Mycont : nullptr;
12911308
}
12921309

1293-
#if _ITERATOR_DEBUG_LEVEL == 2
1294-
void _Orphan_me() noexcept {
1295-
_Lockit _Lock(_LOCK_DEBUG);
1296-
if (_Myproxy) { // adopted, remove self from list
1297-
_Iterator_base12** _Pnext = &_Myproxy->_Myfirstiter;
1298-
while (*_Pnext && *_Pnext != this) {
1299-
_Pnext = &(*_Pnext)->_Mynextiter;
1300-
}
1301-
1302-
_STL_VERIFY(*_Pnext, "ITERATOR LIST CORRUPTED!");
1303-
*_Pnext = _Mynextiter;
1304-
_Myproxy = nullptr;
1305-
}
1306-
}
1307-
#endif // _ITERATOR_DEBUG_LEVEL == 2
1308-
13091310
static constexpr bool _Unwrap_when_unverified = _ITERATOR_DEBUG_LEVEL == 0;
13101311

13111312
_Container_proxy* _Myproxy;
13121313
_Iterator_base12* _Mynextiter;
13131314
};
13141315

13151316
// MEMBER FUNCTIONS FOR _Container_base12
1316-
inline void _Container_base12::_Orphan_all_impl() noexcept {
1317-
if (_Myproxy) { // proxy allocated, drain it
1318-
_Lockit _Lock(_LOCK_DEBUG);
1319-
for (auto _Pnext = &_Myproxy->_Myfirstiter; *_Pnext; *_Pnext = (*_Pnext)->_Mynextiter) {
1320-
(*_Pnext)->_Myproxy = nullptr;
1321-
}
1322-
1323-
_Myproxy->_Myfirstiter = nullptr;
1317+
_CONSTEXPR20_DYNALLOC void _Container_base12::_Orphan_all_unlocked() noexcept {
1318+
for (auto _Pnext = &_Myproxy->_Myfirstiter; *_Pnext; *_Pnext = (*_Pnext)->_Mynextiter) {
1319+
(*_Pnext)->_Myproxy = nullptr;
13241320
}
1321+
_Myproxy->_Myfirstiter = nullptr;
1322+
}
1323+
1324+
inline void _Container_base12::_Orphan_all_locked() noexcept {
1325+
_Lockit _Lock(_LOCK_DEBUG);
1326+
_Orphan_all_unlocked();
13251327
}
13261328

13271329
_CONSTEXPR20_DYNALLOC void _Container_base12::_Orphan_all() noexcept {
13281330
#if _ITERATOR_DEBUG_LEVEL == 2
1331+
if (_Myproxy) { // proxy allocated, drain it
13291332
#ifdef __cpp_lib_is_constant_evaluated
1330-
if (!_STD is_constant_evaluated())
1333+
if (_STD is_constant_evaluated()) {
1334+
_Orphan_all_unlocked();
1335+
} else
13311336
#endif // __cpp_lib_is_constant_evaluated
1332-
{
1333-
_Orphan_all_impl();
1337+
{
1338+
_Orphan_all_locked();
1339+
}
13341340
}
13351341
#endif // _ITERATOR_DEBUG_LEVEL == 2
13361342
}
13371343

1338-
inline void _Container_base12::_Swap_proxy_and_iterators_impl(_Container_base12& _Right) noexcept {
1339-
#if _ITERATOR_DEBUG_LEVEL == 2
1340-
_Lockit _Lock(_LOCK_DEBUG);
1341-
#endif // _ITERATOR_DEBUG_LEVEL == 2
1344+
_CONSTEXPR20_DYNALLOC void _Container_base12::_Swap_proxy_and_iterators_unlocked(_Container_base12& _Right) noexcept {
13421345
_Container_proxy* _Temp = _Myproxy;
13431346
_Myproxy = _Right._Myproxy;
13441347
_Right._Myproxy = _Temp;
@@ -1352,13 +1355,24 @@ inline void _Container_base12::_Swap_proxy_and_iterators_impl(_Container_base12&
13521355
}
13531356
}
13541357

1358+
inline void _Container_base12::_Swap_proxy_and_iterators_locked(_Container_base12& _Right) noexcept {
1359+
_Lockit _Lock(_LOCK_DEBUG);
1360+
_Swap_proxy_and_iterators_unlocked(_Right);
1361+
}
1362+
13551363
_CONSTEXPR20_DYNALLOC void _Container_base12::_Swap_proxy_and_iterators(_Container_base12& _Right) noexcept {
1364+
#if _ITERATOR_DEBUG_LEVEL != 2
1365+
_Swap_proxy_and_iterators_unlocked(_Right);
1366+
#else // ^^^ _ITERATOR_DEBUG_LEVEL != 2 ^^^ / vvv _ITERATOR_DEBUG_LEVEL == 2 vvv
13561367
#ifdef __cpp_lib_is_constant_evaluated
1357-
if (!_STD is_constant_evaluated())
1368+
if (_STD is_constant_evaluated()) {
1369+
_Swap_proxy_and_iterators_unlocked(_Right);
1370+
} else
13581371
#endif // __cpp_lib_is_constant_evaluated
13591372
{
1360-
_Swap_proxy_and_iterators_impl(_Right);
1373+
_Swap_proxy_and_iterators_locked(_Right);
13611374
}
1375+
#endif // _ITERATOR_DEBUG_LEVEL == 2
13621376
}
13631377

13641378
#if _ITERATOR_DEBUG_LEVEL == 0

0 commit comments

Comments
 (0)