On 31/05/17 22:28 +0200, François Dumont wrote:
Unless I made a mistake it revealed that restoring explicit call to _Bit_alloc_type() in default constructor was not enough. G++ doesn't transform it into a value-init if needed. I don't know if it is a compiler bug but I had to do just like presented in the Standard to achieve the expected behavior.
That really shouldn't be necessary (see blow).
This value-init is specific to post-C++11 right ? Maybe I could remove the useless explicit call to _Bit_alloc_type() in pre-C++11 mode ?
No, because C++03 also requires the allocator to be value-initialized.
Now I wonder if I really introduced a regression in rb_tree...
Yes, I think you did. Could you try to verify that using the new default_init_allocator?
+ struct _Bvector_impl + : public _Bit_alloc_type, public _Bvector_impl_data + { + public: +#if __cplusplus >= 201103L + _Bvector_impl() + noexcept( noexcept(_Bit_alloc_type()) + && noexcept(_Bvector_impl(declval<const _Bit_alloc_type&>())) )
This second condition is not needed, because that constructor should be noexcept (see below).
+ : _Bvector_impl(_Bit_alloc_type())
This should not be necessary...
+ { } +#else _Bvector_impl() - : _Bit_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage() + : _Bit_alloc_type() { } +#endif
I would expect the constructor to look like this: _Bvector_impl() _GLIBCXX_NOEXCEPT_IF( noexcept(_Bit_alloc_type()) ) : _Bit_alloc_type() { } What happens when you do that?
_Bvector_impl(const _Bit_alloc_type& __a) - : _Bit_alloc_type(__a), _M_start(), _M_finish(), _M_end_of_storage() + _GLIBCXX_NOEXCEPT_IF( noexcept(_Bit_alloc_type(__a)) )
Copying the allocator is not allowed to throw. You can use simply _GLIBCXX_NOEXCEPT here.
+void test01() +{ + typedef default_init_allocator<T> alloc_type; + typedef std::vector<T, alloc_type> test_type; + + test_type v1; + v1.push_back(T()); + + VERIFY( !v1.empty() ); + VERIFY( !v1.get_allocator().state );
This is unlikely to ever fail, because the stack is probably full of zeros anyway. Did you confirm whether the test fails without your fixes to value-initialize the allocator? One possible way to make it fail would be to construct the vector<bool> using placement new, into a buffer filled with non-zero values. (Valgrind or a sanitizer should also tell us, but we can't rely on them in the testsuite).