PR libstdc++/80893 Fix null dereference in vector<bool>
PR libstdc++/80893 * include/bits/stl_bvector.h (vector<bool>::_M_initialize): Avoid null pointer dereference when size is zero. * testsuite/23_containers/vector/bool/80893.cc: New. * testsuite/util/testsuite_allocator.h (PointerBase::PointerBase): Add non-explicit constructor from nullptr. (PointerBase::derived() const): Add const-qualified overload. From-SVN: r248734
This commit is contained in:
parent
bde63fdea4
commit
046a84762b
@ -1,3 +1,13 @@
|
||||
2017-05-31 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/80893
|
||||
* include/bits/stl_bvector.h (vector<bool>::_M_initialize): Avoid
|
||||
null pointer dereference when size is zero.
|
||||
* testsuite/23_containers/vector/bool/80893.cc: New.
|
||||
* testsuite/util/testsuite_allocator.h (PointerBase::PointerBase):
|
||||
Add non-explicit constructor from nullptr.
|
||||
(PointerBase::derived() const): Add const-qualified overload.
|
||||
|
||||
2017-05-20 Tim Shen <timshen@google.com>
|
||||
|
||||
PR libstdc++/80737
|
||||
|
@ -1088,10 +1088,18 @@ template<typename _Alloc>
|
||||
|
||||
void
|
||||
_M_initialize(size_type __n)
|
||||
{
|
||||
if (__n)
|
||||
{
|
||||
_Bit_pointer __q = this->_M_allocate(__n);
|
||||
this->_M_impl._M_end_of_storage = __q + _S_nword(__n);
|
||||
this->_M_impl._M_start = iterator(std::__addressof(*__q), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_M_impl._M_end_of_storage = _Bit_pointer();
|
||||
this->_M_impl._M_start = iterator(0, 0);
|
||||
}
|
||||
this->_M_impl._M_finish = this->_M_impl._M_start + difference_type(__n);
|
||||
}
|
||||
|
||||
|
74
libstdc++-v3/testsuite/23_containers/vector/bool/80893.cc
Normal file
74
libstdc++-v3/testsuite/23_containers/vector/bool/80893.cc
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright (C) 2017 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/>.
|
||||
|
||||
// libstdc++/80893
|
||||
|
||||
#include <vector>
|
||||
#include <testsuite_allocator.h>
|
||||
|
||||
struct DereferencedInvalidPointer { };
|
||||
|
||||
// User-defined pointer type that throws if a null pointer is dereferenced.
|
||||
template<typename T>
|
||||
struct Pointer : __gnu_test::PointerBase<Pointer<T>, T>
|
||||
{
|
||||
using __gnu_test::PointerBase<Pointer<T>, T>::PointerBase;
|
||||
|
||||
T& operator*() const
|
||||
{
|
||||
if (!this->value)
|
||||
throw DereferencedInvalidPointer();
|
||||
return *this->value;
|
||||
}
|
||||
};
|
||||
|
||||
// Minimal allocator using Pointer<T>
|
||||
template<typename T>
|
||||
struct Alloc
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef Pointer<T> pointer;
|
||||
|
||||
Alloc() = default;
|
||||
template<typename U>
|
||||
Alloc(const Alloc<U>&) { }
|
||||
|
||||
pointer allocate(std::size_t n)
|
||||
{
|
||||
if (n)
|
||||
return pointer(std::allocator<T>().allocate(n));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void deallocate(pointer p, std::size_t n)
|
||||
{
|
||||
if (n)
|
||||
std::allocator<T>().deallocate(p.value, n);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
bool operator==(Alloc<T>, Alloc<T>) { return true; }
|
||||
|
||||
template<typename T>
|
||||
bool operator!=(Alloc<T>, Alloc<T>) { return false; }
|
||||
|
||||
int main()
|
||||
{
|
||||
std::vector<bool, Alloc<bool>> v(0);
|
||||
std::vector<bool, Alloc<bool>> w(v);
|
||||
}
|
@ -570,6 +570,8 @@ namespace __gnu_test
|
||||
|
||||
explicit PointerBase(T* p = nullptr) : value(p) { }
|
||||
|
||||
PointerBase(std::nullptr_t) : value(nullptr) { }
|
||||
|
||||
template<typename D, typename U,
|
||||
typename = decltype(static_cast<T*>(std::declval<U*>()))>
|
||||
PointerBase(const PointerBase<D, U>& p) : value(p.value) { }
|
||||
@ -603,7 +605,11 @@ namespace __gnu_test
|
||||
}
|
||||
|
||||
private:
|
||||
Derived& derived() { return static_cast<Derived&>(*this); }
|
||||
Derived&
|
||||
derived() { return static_cast<Derived&>(*this); }
|
||||
|
||||
const Derived&
|
||||
derived() const { return static_cast<const Derived&>(*this); }
|
||||
};
|
||||
|
||||
template<typename D, typename T>
|
||||
|
Loading…
Reference in New Issue
Block a user