From: redi Date: Wed, 29 Jan 2014 14:57:42 +0000 (+0000) Subject: PR libstdc++/59829 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f29863eed95c1a1f66fa5ec63ec8cac8aa1f6585;p=thirdparty%2Fgcc.git PR libstdc++/59829 * include/bits/stl_vector.h (vector::data()): Call _M_data_ptr. (vector::_M_data_ptr): New overloaded functions to ensure empty vectors do not dereference the pointer. * testsuite/23_containers/vector/59829.cc: New. * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc: Adjust dg-error line number. * testsuite/23_containers/vector/requirements/dr438/ constructor_1_neg.cc: Likewise. * testsuite/23_containers/vector/requirements/dr438/ constructor_2_neg.cc: Likewise. * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@207241 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 9618c9eb275e..9578071f478d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -24,6 +24,20 @@ New. * testsuite/20_util/allocator_traits/requirements/typedefs2.cc: New. + PR libstdc++/59829 + * include/bits/stl_vector.h (vector::data()): Call _M_data_ptr. + (vector::_M_data_ptr): New overloaded functions to ensure empty + vectors do not dereference the pointer. + * testsuite/23_containers/vector/59829.cc: New. + * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc: + Adjust dg-error line number. + * testsuite/23_containers/vector/requirements/dr438/ + constructor_1_neg.cc: Likewise. + * testsuite/23_containers/vector/requirements/dr438/ + constructor_2_neg.cc: Likewise. + * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc: + Likewise. + 2014-01-28 Jonathan Wakely Kyle Lippincott diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 98ac708e8f16..7e52fde55b1b 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -888,7 +888,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER pointer #endif data() _GLIBCXX_NOEXCEPT - { return std::__addressof(front()); } + { return _M_data_ptr(this->_M_impl._M_start); } #if __cplusplus >= 201103L const _Tp* @@ -896,7 +896,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const_pointer #endif data() const _GLIBCXX_NOEXCEPT - { return std::__addressof(front()); } + { return _M_data_ptr(this->_M_impl._M_start); } // [23.2.4.3] modifiers /** @@ -1470,6 +1470,23 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } } #endif + +#if __cplusplus >= 201103L + template + _Up* + _M_data_ptr(_Up* __ptr) const + { return __ptr; } + + template + typename std::pointer_traits<_Ptr>::element_type* + _M_data_ptr(_Ptr __ptr) const + { return empty() ? nullptr : std::__addressof(*__ptr); } +#else + template + _Ptr + _M_data_ptr(_Ptr __ptr) const + { return __ptr; } +#endif }; diff --git a/libstdc++-v3/testsuite/23_containers/vector/59829.cc b/libstdc++-v3/testsuite/23_containers/vector/59829.cc new file mode 100644 index 000000000000..1818c8941ec0 --- /dev/null +++ b/libstdc++-v3/testsuite/23_containers/vector/59829.cc @@ -0,0 +1,67 @@ +// Copyright (C) 2014 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 +// . + +// { dg-options "-std=gnu++11" } + +// libstdc++/59829 + +#include +#include + +// User-defined pointer type that throws if a null pointer is dereferenced. +template +struct Pointer : __gnu_test::PointerBase, T> +{ + using __gnu_test::PointerBase, T>::PointerBase; + + T& operator*() const + { + if (!this->value) + throw "Dereferenced invalid pointer"; + return *this->value; + } +}; + +// Minimal allocator using Pointer +template +struct Alloc +{ + typedef T value_type; + typedef Pointer pointer; + + Alloc() = default; + template + Alloc(const Alloc&) { } + + pointer allocate(std::size_t n) + { return pointer(std::allocator().allocate(n)); } + + void deallocate(pointer p, std::size_t n) + { std::allocator().deallocate(p.value, n); } +}; + +template +bool operator==(Alloc l, Alloc r) { return true; } + +template +bool operator!=(Alloc l, Alloc r) { return false; } + +int main() +{ + std::vector> a; + a.data(); +} diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc index a12b11673354..191fbc7bfdb3 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc @@ -18,7 +18,7 @@ // . // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1316 } +// { dg-error "no matching" "" { target *-*-* } 1320 } #include diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc index b839cccc894a..8818a88ccd77 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc @@ -18,7 +18,7 @@ // . // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1242 } +// { dg-error "no matching" "" { target *-*-* } 1246 } #include diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc index e9e966b792a8..09499bcbad7a 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc @@ -18,7 +18,7 @@ // . // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1242 } +// { dg-error "no matching" "" { target *-*-* } 1246 } #include #include diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc index 71c6c496e2ab..674e3b5d6e50 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc @@ -18,7 +18,7 @@ // . // { dg-do compile } -// { dg-error "no matching" "" { target *-*-* } 1357 } +// { dg-error "no matching" "" { target *-*-* } 1361 } #include