Skip to content

Commit d410121

Browse files
committed
Fix test failure of default_init with advanced optimizers like GCC-16, since operator new ends the lifetime of the previous value.
1 parent 1713116 commit d410121

1 file changed

Lines changed: 32 additions & 4 deletions

File tree

test/allocator_traits_test.cpp

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,16 @@ class copymovable
237237
{ return moved_; }
238238
};
239239

240+
//'default_init' must leave the storage uninitialized, unlike 'value_init' which
241+
//zero-initializes it. Observing "left as-is" means reading the bytes written before
242+
//construct(); but construct() ends the previous object's lifetime, so that read is of an
243+
//indeterminate value and a modern optimizer may legally drop the prior store
244+
//and fold the read to anything. Routing the pre-store and the post-read through volatile
245+
//glvalues prevents the store from being elided and forces a real memory load, so the test
246+
//observes the actual (untouched) bytes.
247+
inline void test_volatile_store(int &i, int v){ *static_cast<volatile int *>(&i) = v; }
248+
inline int test_volatile_load (int &i){ return *static_cast<volatile int *>(&i); }
249+
240250
void test_void_allocator()
241251
{
242252
boost::container::allocator_traits<std::allocator<void> > stdtraits; (void)stdtraits;
@@ -379,9 +389,19 @@ int main()
379389
BOOST_TEST(c_alloc.construct_called() && !c.copymoveconstructed() && !c.moved());
380390
}
381391
{
382-
int i = 5;
392+
//gcc-16 considers the object uninitialized after the default-init placement-new and warns
393+
//on the (intentional) volatile read-back below; the warning is spurious here, so silence it.
394+
#if defined(__GNUC__)
395+
#pragma GCC diagnostic push
396+
#pragma GCC diagnostic ignored "-Wuninitialized"
397+
#endif
398+
int i = 0;
399+
test_volatile_store(i, 5);
383400
CAllocTraits::construct(c_alloc, &i, boost::container::default_init);
384-
BOOST_TEST(c_alloc.construct_called() && i == 5);
401+
BOOST_TEST(c_alloc.construct_called() && test_volatile_load(i) == 5);
402+
#if defined(__GNUC__)
403+
#pragma GCC diagnostic pop
404+
#endif
385405
}
386406
{
387407
copymovable c;
@@ -403,9 +423,17 @@ int main()
403423
BOOST_TEST(!c.copymoveconstructed() && !c.moved());
404424
}
405425
{
406-
int i = 4;
426+
#if defined(__GNUC__)
427+
#pragma GCC diagnostic push
428+
#pragma GCC diagnostic ignored "-Wuninitialized"
429+
#endif
430+
int i = 0;
431+
test_volatile_store(i, 4);
407432
SAllocTraits::construct(s_alloc, &i, boost::container::default_init);
408-
BOOST_TEST(i == 4);
433+
BOOST_TEST(test_volatile_load(i) == 4);
434+
#if defined(__GNUC__)
435+
#pragma GCC diagnostic pop
436+
#endif
409437
}
410438
{
411439
copymovable c;

0 commit comments

Comments
 (0)