* Re: PR 57779 New debug check [not found] ` <51F050BC.1060106@oracle.com> @ 2013-07-31 20:01 ` François Dumont 2013-07-31 22:40 ` Paolo Carlini 0 siblings, 1 reply; 6+ messages in thread From: François Dumont @ 2013-07-31 20:01 UTC (permalink / raw) To: Paolo Carlini; +Cc: Jonathan Wakely, libstdc++, gcc-patches [-- Attachment #1: Type: text/plain, Size: 1250 bytes --] Here is another proposal using std::common_type to find out how to instantiate std::less and std::greater_equal. Much easier with C++11 features indeed. Tested under linux x86_64 debug mode. Ok to commit ? François On 07/25/2013 12:10 AM, Paolo Carlini wrote: > On 07/24/2013 10:41 PM, François Dumont wrote: >> On 07/24/2013 10:49 AM, Paolo Carlini wrote: >>> Hi, >>> >>> I didn't follow the finest details of this (Jonathan will be able to >>> provide better comments) but it's not immediately obvious to me what >>> happens of the -1 + 1 trick when begin() == end(). >>> >>> In my opinion, we should not add to cpp_type_traits.h, which would >>> become bigger even in normal-mode (in fact we would like to see it >>> going away...) >>> >>> Paolo. >>> >> The -1 +1 trick only take place if begin() != end(). > Ah good. >> Do you want me to make part of the check only active in C++11 mode so >> that I simply rely on C++11 features ? > Well, yes, I didn't consider that, but if it makes things much easier, > it seems a good idea. Given the way the headers are already structured > I think it's possible in c++11 mode to have std::less & co without, > eg, the big std::function, then the idea makes a lot of sense. > > Paolo. > [-- Attachment #2: 57779.patch --] [-- Type: text/x-patch, Size: 19387 bytes --] Index: include/debug/macros.h =================================================================== --- include/debug/macros.h (revision 201251) +++ include/debug/macros.h (working copy) @@ -72,11 +72,11 @@ */ #define __glibcxx_check_insert(_Position) \ _GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \ - _M_message(__gnu_debug::__msg_insert_singular) \ + _M_message(__gnu_debug::__msg_insert_singular) \ ._M_sequence(*this, "this") \ ._M_iterator(_Position, #_Position)); \ _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ - _M_message(__gnu_debug::__msg_insert_different) \ + _M_message(__gnu_debug::__msg_insert_different) \ ._M_sequence(*this, "this") \ ._M_iterator(_Position, #_Position)) @@ -101,15 +101,16 @@ * that it reference the sequence we are inserting into, and that the * iterator range [_First, Last) is a valid (possibly empty) * range. Note that this macro is only valid when the container is a - * _Safe_sequence and the iterator is a _Safe_iterator. - * - * @todo We would like to be able to check for noninterference of - * _Position and the range [_First, _Last), but that can't (in - * general) be done. + * _Safe_sequence and the _Position iterator is a _Safe_iterator. */ #define __glibcxx_check_insert_range(_Position,_First,_Last) \ __glibcxx_check_valid_range(_First,_Last); \ -__glibcxx_check_insert(_Position) +__glibcxx_check_insert(_Position); \ +_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__foreign_iterator(_Position,_First),\ + _M_message(__gnu_debug::__msg_insert_range_from_self)\ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_sequence(*this, "this")) /** Verify that we can insert the values in the iterator range * [_First, _Last) into *this after the iterator _Position. Insertion @@ -332,7 +333,7 @@ _M_message(__gnu_debug::__msg_valid_load_factor) \ ._M_sequence(*this, "this")) -#define __glibcxx_check_equal_allocs(_Other) \ +#define __glibcxx_check_equal_allocs(_Other) \ _GLIBCXX_DEBUG_VERIFY(this->get_allocator() == _Other.get_allocator(), \ _M_message(__gnu_debug::__msg_equal_allocs) \ ._M_sequence(*this, "this")) Index: include/debug/list =================================================================== --- include/debug/list (revision 201251) +++ include/debug/list (working copy) @@ -791,4 +791,11 @@ } // namespace __debug } // namespace std +namespace __gnu_debug +{ + template<class _Tp, class _Alloc> + struct _Insert_range_from_self_is_safe<std::__debug::list<_Tp, _Alloc> > + { enum { __value = 1 }; }; +} + #endif Index: include/debug/formatter.h =================================================================== --- include/debug/formatter.h (revision 201251) +++ include/debug/formatter.h (working copy) @@ -114,7 +114,9 @@ // unordered container buckets __msg_bucket_index_oob, __msg_valid_load_factor, - __msg_equal_allocs + // others + __msg_equal_allocs, + __msg_insert_range_from_self }; class _Error_formatter Index: include/debug/functions.h =================================================================== --- include/debug/functions.h (revision 201251) +++ include/debug/functions.h (working copy) @@ -32,7 +32,11 @@ #include <bits/c++config.h> #include <bits/stl_iterator_base_types.h> // for iterator_traits, categories and // _Iter_base -#include <bits/cpp_type_traits.h> // for __is_integer +#include <bits/cpp_type_traits.h> // for __is_integer +#if __cplusplus >= 201103L +# include <bits/stl_function.h> // for less and greater_equal +# include <type_traits> // for common_type +#endif #include <debug/formatter.h> namespace __gnu_debug @@ -40,6 +44,10 @@ template<typename _Iterator, typename _Sequence> class _Safe_iterator; + template<typename _Sequence> + struct _Insert_range_from_self_is_safe + { enum { __value = 0 }; }; + // An arbitrary iterator pointer is not singular. inline bool __check_singular_aux(const void*) { return false; } @@ -162,6 +170,127 @@ return __first; } +#if __cplusplus >= 201103L + template<typename _Iterator, typename _Sequence, + typename _InputIterator, + typename _PointerType1, + typename _PointerType2> + inline bool + __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, + _PointerType1, _PointerType2) + { + typedef typename std::common_type<_PointerType1, + _PointerType2>::type _PointerType; + std::less<_PointerType> __l; + std::greater_equal<_PointerType> __ge; + + return + __l(std::addressof(*__other), + std::addressof(*(__it._M_get_sequence()->_M_base().begin()))) + || __ge(std::addressof(*__other), + std::addressof(*(__it._M_get_sequence()->_M_base().end() - 1)) + 1); + + } + + template<typename _Iterator, typename _Sequence, typename _InputIterator> + inline bool + __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, + std::true_type) + { + // Only containers with all elements in contiguous memory can have their + // elements passed through pointers. + // Arithmetics is here just to make sure we are not dereferencing + // past-the-end iterator. + if (__it._M_get_sequence()->_M_base().begin() + != __it._M_get_sequence()->_M_base().end()) + if (std::__addressof(*(__it._M_get_sequence()->_M_base().end() - 1)) + - std::__addressof(*(__it._M_get_sequence()->_M_base().begin())) + == __it._M_get_sequence()->size() - 1) + return __foreign_iterator_aux4(__it, __other, + std::addressof(*(__it._M_get_sequence()->_M_base().begin())), + std::addressof(*__other)); + return true; + } + + /* Fallback overload for which we can't say, assume it is valid. */ + template<typename _Iterator, typename _Sequence, typename _InputIterator> + inline bool + __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, + std::false_type) + { return true; } +#endif + + /** Checks that iterators do not belong to the same sequence. */ + template<typename _Iterator, typename _Sequence, typename _OtherIterator> + inline bool + __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it, + const _Safe_iterator<_OtherIterator, _Sequence>& __other, + std::input_iterator_tag) + { + return +#ifndef _GLIBCXX_DEBUG_PEDANTIC + _Insert_range_from_self_is_safe<_Sequence>::__value || +#endif + __it._M_get_sequence() != __other._M_get_sequence(); + } + +#if __cplusplus >= 201103L + /* This overload detects when passing pointers to the contained elements rather + than using iterators. + */ + template<typename _Iterator, typename _Sequence, typename _InputIterator> + inline bool + __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, + std::random_access_iterator_tag) + { + typedef typename _Sequence::const_iterator _ItType; + typedef typename std::iterator_traits<_ItType>::reference _Ref; + return __foreign_iterator_aux3(__it, __other, + std::is_lvalue_reference<_Ref>()); + } +#endif + + /* Fallback overload for which we can't say, assume it is valid. */ + template<typename _Iterator, typename _Sequence, typename _InputIterator> + inline bool + __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>&, + _InputIterator, + std::input_iterator_tag) + { return true; } + + template<typename _Iterator, typename _Sequence, + typename _Integral> + inline bool + __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it, + _Integral __other, + std::__true_type) + { return true; } + + template<typename _Iterator, typename _Sequence, + typename _InputIterator> + inline bool + __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, + std::__false_type) + { + return __foreign_iterator_aux2(__it, __other, + std::__iterator_category(__it)); + } + + template<typename _Iterator, typename _Sequence, + typename _InputIterator> + inline bool + __foreign_iterator(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + return __foreign_iterator_aux(__it, __other, _Integral()); + } + /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ template<typename _CharT, typename _Integer> inline const _CharT* Index: include/debug/forward_list =================================================================== --- include/debug/forward_list (revision 201251) +++ include/debug/forward_list (working copy) @@ -796,6 +796,11 @@ _S_Is_Beginnest(_BaseIt __it, const _Sequence* __seq) { return _S_Is(__it, __seq); } }; + + template<class _Tp, class _Alloc> + struct _Insert_range_from_self_is_safe< + std::__debug::forward_list<_Tp, _Alloc> > + { enum { __value = 1 }; }; } #endif Index: testsuite/util/debug/checks.h =================================================================== --- testsuite/util/debug/checks.h (revision 201251) +++ testsuite/util/debug/checks.h (working copy) @@ -129,7 +129,7 @@ c2.assign(last, first); // Expected failure } - // Check that invalid range of debug !random debug iterators is detected + // Check that invalid range of debug not random iterators is detected template<typename _Tp> void check_assign3() @@ -377,6 +377,34 @@ } template<typename _Tp> + void + check_insert4() + { + bool test __attribute__((unused)) = true; + + typedef _Tp cont_type; + typedef typename cont_type::value_type cont_val_type; + typedef typename CopyableValueType<cont_val_type>::value_type val_type; + typedef std::list<val_type> list_type; + + generate_unique<val_type> gu; + + list_type l; + for (int i = 0; i != 5; ++i) + l.push_back(gu.build()); + VERIFY(l.size() == 5); + + typename list_type::iterator first = l.begin(); ++first; + typename list_type::iterator last = first; ++last; ++last; + + cont_type c1; + InsertRangeHelper<cont_type>::Insert(c1, l.begin(), l.end()); + VERIFY(c1.size() == 5); + + c1.insert(c1.begin(), c1.begin(), c1.end()); // Expected failure. + } + + template<typename _Tp> void use_invalid_iterator() { bool test __attribute__((unused)) = true; Index: testsuite/23_containers/vector/debug/insert5_neg.cc =================================================================== --- testsuite/23_containers/vector/debug/insert5_neg.cc (revision 0) +++ testsuite/23_containers/vector/debug/insert5_neg.cc (revision 0) @@ -0,0 +1,33 @@ +// Copyright (C) 2013 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/>. +// +// { dg-require-debug-mode "" } +// { dg-do run { xfail *-*-* } } + +#include <vector> +#include <debug/checks.h> + +void test01() +{ + __gnu_test::check_insert4<std::vector<int> >(); +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/vector/debug/insert6_neg.cc =================================================================== --- testsuite/23_containers/vector/debug/insert6_neg.cc (revision 0) +++ testsuite/23_containers/vector/debug/insert6_neg.cc (revision 0) @@ -0,0 +1,48 @@ +// Copyright (C) 2013 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/>. +// +// { dg-do run { xfail *-*-* } } + +#include <vector> +#include <debug/vector> +#include <debug/checks.h> + +void test01() +{ + std::vector<bool> v; + __gnu_debug::vector<bool> dv; + for (int i = 0; i != 10; ++i) + { + v.push_back((i % 2) != 0); + dv.push_back((i % 2) == 0); + } + + dv.insert(dv.begin(), v.begin(), v.begin() + 5); + VERIFY( dv.size() == 15 ); +} + +void test02() +{ + __gnu_test::check_insert4<__gnu_debug::vector<bool> >(); +} + +int main() +{ + test01(); + test02(); + return 0; +} Index: testsuite/23_containers/vector/debug/57779_neg.cc =================================================================== --- testsuite/23_containers/vector/debug/57779_neg.cc (revision 0) +++ testsuite/23_containers/vector/debug/57779_neg.cc (revision 0) @@ -0,0 +1,38 @@ +// Copyright (C) 2013 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/>. +// +// { dg-options "-std=gnu++11" } +// { dg-require-debug-mode "" } +// { dg-do run { xfail *-*-* } } + +#include <vector> +#include <debug/checks.h> + +void test01() +{ + std::vector<int> v; + for (int i = 0; i != 10; ++i) + v.push_back(i); + + v.insert(v.begin(), v.data() + 1, v.data() + 5); // Expected failure +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/deque/debug/insert5_neg.cc =================================================================== --- testsuite/23_containers/deque/debug/insert5_neg.cc (revision 0) +++ testsuite/23_containers/deque/debug/insert5_neg.cc (revision 0) @@ -0,0 +1,33 @@ +// Copyright (C) 2013 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/>. +// +// { dg-require-debug-mode "" } +// { dg-do run { xfail *-*-* } } + +#include <deque> +#include <debug/checks.h> + +void test01() +{ + __gnu_test::check_insert4<std::deque<int> >(); +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/list/debug/insert5_neg.cc =================================================================== --- testsuite/23_containers/list/debug/insert5_neg.cc (revision 0) +++ testsuite/23_containers/list/debug/insert5_neg.cc (revision 0) @@ -0,0 +1,34 @@ +// Copyright (C) 2013 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/>. +// +// { dg-require-debug-mode "" } +// { dg-options "-D_GLIBCXX_DEBUG_PEDANTIC" } +// { dg-do run { xfail *-*-* } } + +#include <list> +#include <debug/checks.h> + +void test01() +{ + __gnu_test::check_insert4<std::list<int> >(); +} + +int main() +{ + test01(); + return 0; +} Index: src/c++11/debug.cc =================================================================== --- src/c++11/debug.cc (revision 201251) +++ src/c++11/debug.cc (working copy) @@ -181,7 +181,8 @@ "attempt to access container with out-of-bounds bucket index %2;," " container only holds %3; buckets", "load factor shall be positive", - "allocators must be equal" + "allocators must be equal", + "attempt to insert with an iterator range [%1.name;, %2.name;) from this container" }; void @@ -695,7 +696,7 @@ } __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p\n", - _M_variant._M_sequence._M_address); + _M_variant._M_iterator._M_sequence); __formatter->_M_print_word(__buf); } __formatter->_M_print_word("}\n"); @@ -808,8 +809,11 @@ if (__length == 0) return; - if ((_M_column + __length < _M_max_length) - || (__length >= _M_max_length && _M_column == 1)) + size_t __visual_length + = __word[__length - 1] == '\n' ? __length - 1 : __length; + if (__visual_length == 0 + || (_M_column + __visual_length < _M_max_length) + || (__visual_length >= _M_max_length && _M_column == 1)) { // If this isn't the first line, indent if (_M_column == 1 && !_M_first_line) @@ -823,17 +827,17 @@ } fprintf(stderr, "%s", __word); - _M_column += __length; if (__word[__length - 1] == '\n') { _M_first_line = false; _M_column = 1; } + else + _M_column += __length; } else { - _M_column = 1; _M_print_word("\n"); _M_print_word(__word); } ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: PR 57779 New debug check 2013-07-31 20:01 ` PR 57779 New debug check François Dumont @ 2013-07-31 22:40 ` Paolo Carlini 2013-08-01 20:00 ` François Dumont 0 siblings, 1 reply; 6+ messages in thread From: Paolo Carlini @ 2013-07-31 22:40 UTC (permalink / raw) To: François Dumont; +Cc: Jonathan Wakely, libstdc++, gcc-patches On 07/31/2013 09:58 PM, François Dumont wrote: > Here is another proposal using std::common_type to find out how to > instantiate std::less and std::greater_equal. Much easier with C++11 > features indeed. > > Tested under linux x86_64 debug mode. > > Ok to commit ? Ok, thanks! Paolo. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: PR 57779 New debug check 2013-07-31 22:40 ` Paolo Carlini @ 2013-08-01 20:00 ` François Dumont 0 siblings, 0 replies; 6+ messages in thread From: François Dumont @ 2013-08-01 20:00 UTC (permalink / raw) To: Paolo Carlini; +Cc: Jonathan Wakely, libstdc++, gcc-patches [-- Attachment #1: Type: text/plain, Size: 2525 bytes --] Attached patch applied. Compare to the proposed one I had to: - Disable the new check for __gnu_debug::basic_string<>, it is supported following Standard words. To do so I had to slithly review how _GLIBCXX_DEBUG_PEDANTIC was managed. - Add check on forward_list::insert_after 2013-08-01 François Dumont <fdumont@gcc.gnu.org> PR libstdc++/57779 * include/debug/formatter.h (_Debug_msg_id): Add __msg_insert_itself_range entry. * include/debug/functions.h (_Insert_range_from_self_is_safe<>): New, indicate container types supporting self range insertion in GNU implementation. (__foreign_iterator): New, check if an iterator points to a given sequence. * include/debug/macros.h (__glibcxx_check_insert_range): Add check using __foreign_iterator. (__gibcxx_check_insert_range_after): Likewise. * include/debug/string (_Insert_range_from_self_is_safe<>): Partially specialized to mark __gnu_debug::basic_string<> as supporting self range insert. * include/debug/list (_Insert_range_from_self_is_safe<>): Partially specialized to mark std::list as supporting self range insert if _GLIBCXX_DEBUG_PEDANTIC is not defined. * include/debug/forward_list (_Insert_range_from_self_is_safe<>): Likewise. * src/c++11/debug.cc (_S_debug_messages): Add __msg_insert_itself_range_entry message. (_Error_formatter::_Parameter::_M_print_description): Display iterator sequence address rather than sequence address when the parameter type is an iterator. (_Error_formatter::_M_print_word): Enhance behavior when displaying a word with an appended '\n'. * testsuite/util/debug/checks.h (check_insert4<>): New. * testsuite/23_containers/deque/debug/insert5_neg.cc: New. * testsuite/23_containers/vector/debug/insert5_neg.cc: Likewise. * testsuite/23_containers/vector/debug/insert6_neg.cc: Likewise. * testsuite/23_containers/vector/debug/57779_neg.cc: Likewise. * testsuite/23_containers/list/debug/insert5_neg.cc: Likewise. * testsuite/23_containers/forward_list/debug/insert_after4_neg.cc: Likewise. François On 07/31/2013 11:50 PM, Paolo Carlini wrote: > On 07/31/2013 09:58 PM, François Dumont wrote: >> Here is another proposal using std::common_type to find out how to >> instantiate std::less and std::greater_equal. Much easier with C++11 >> features indeed. >> >> Tested under linux x86_64 debug mode. >> >> Ok to commit ? > Ok, thanks! > > Paolo. > [-- Attachment #2: 57779.patch --] [-- Type: text/x-patch, Size: 22015 bytes --] Index: include/debug/formatter.h =================================================================== --- include/debug/formatter.h (revision 201413) +++ include/debug/formatter.h (working copy) @@ -114,7 +114,9 @@ // unordered container buckets __msg_bucket_index_oob, __msg_valid_load_factor, - __msg_equal_allocs + // others + __msg_equal_allocs, + __msg_insert_range_from_self }; class _Error_formatter Index: include/debug/functions.h =================================================================== --- include/debug/functions.h (revision 201413) +++ include/debug/functions.h (working copy) @@ -32,7 +32,11 @@ #include <bits/c++config.h> #include <bits/stl_iterator_base_types.h> // for iterator_traits, categories and // _Iter_base -#include <bits/cpp_type_traits.h> // for __is_integer +#include <bits/cpp_type_traits.h> // for __is_integer +#if __cplusplus >= 201103L +# include <bits/stl_function.h> // for less and greater_equal +# include <type_traits> // for common_type +#endif #include <debug/formatter.h> namespace __gnu_debug @@ -40,6 +44,10 @@ template<typename _Iterator, typename _Sequence> class _Safe_iterator; + template<typename _Sequence> + struct _Insert_range_from_self_is_safe + { enum { __value = 0 }; }; + // An arbitrary iterator pointer is not singular. inline bool __check_singular_aux(const void*) { return false; } @@ -162,6 +170,123 @@ return __first; } +#if __cplusplus >= 201103L + template<typename _Iterator, typename _Sequence, + typename _InputIterator, + typename _PointerType1, + typename _PointerType2> + inline bool + __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, + _PointerType1, _PointerType2) + { + typedef typename std::common_type<_PointerType1, + _PointerType2>::type _PointerType; + std::less<_PointerType> __l; + std::greater_equal<_PointerType> __ge; + + return + __l(std::addressof(*__other), + std::addressof(*(__it._M_get_sequence()->_M_base().begin()))) + || __ge(std::addressof(*__other), + std::addressof(*(__it._M_get_sequence()->_M_base().end() - 1)) + 1); + + } + + template<typename _Iterator, typename _Sequence, typename _InputIterator> + inline bool + __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, + std::true_type) + { + // Only containers with all elements in contiguous memory can have their + // elements passed through pointers. + // Arithmetics is here just to make sure we are not dereferencing + // past-the-end iterator. + if (__it._M_get_sequence()->_M_base().begin() + != __it._M_get_sequence()->_M_base().end()) + if (std::__addressof(*(__it._M_get_sequence()->_M_base().end() - 1)) + - std::__addressof(*(__it._M_get_sequence()->_M_base().begin())) + == __it._M_get_sequence()->size() - 1) + return __foreign_iterator_aux4(__it, __other, + std::addressof(*(__it._M_get_sequence()->_M_base().begin())), + std::addressof(*__other)); + return true; + } + + /* Fallback overload for which we can't say, assume it is valid. */ + template<typename _Iterator, typename _Sequence, typename _InputIterator> + inline bool + __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, + std::false_type) + { return true; } +#endif + + /** Checks that iterators do not belong to the same sequence. */ + template<typename _Iterator, typename _Sequence, typename _OtherIterator> + inline bool + __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it, + const _Safe_iterator<_OtherIterator, _Sequence>& __other, + std::input_iterator_tag) + { return __it._M_get_sequence() != __other._M_get_sequence(); } + +#if __cplusplus >= 201103L + /* This overload detects when passing pointers to the contained elements rather + than using iterators. + */ + template<typename _Iterator, typename _Sequence, typename _InputIterator> + inline bool + __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, + std::random_access_iterator_tag) + { + typedef typename _Sequence::const_iterator _ItType; + typedef typename std::iterator_traits<_ItType>::reference _Ref; + return __foreign_iterator_aux3(__it, __other, + std::is_lvalue_reference<_Ref>()); + } +#endif + + /* Fallback overload for which we can't say, assume it is valid. */ + template<typename _Iterator, typename _Sequence, typename _InputIterator> + inline bool + __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>&, + _InputIterator, + std::input_iterator_tag) + { return true; } + + template<typename _Iterator, typename _Sequence, + typename _Integral> + inline bool + __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it, + _Integral __other, + std::__true_type) + { return true; } + + template<typename _Iterator, typename _Sequence, + typename _InputIterator> + inline bool + __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other, + std::__false_type) + { + return + _Insert_range_from_self_is_safe<_Sequence>::__value + || __foreign_iterator_aux2(__it, __other, + std::__iterator_category(__it)); + } + + template<typename _Iterator, typename _Sequence, + typename _InputIterator> + inline bool + __foreign_iterator(const _Safe_iterator<_Iterator, _Sequence>& __it, + _InputIterator __other) + { + typedef typename std::__is_integer<_InputIterator>::__type _Integral; + return __foreign_iterator_aux(__it, __other, _Integral()); + } + /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ template<typename _CharT, typename _Integer> inline const _CharT* Index: include/debug/forward_list =================================================================== --- include/debug/forward_list (revision 201413) +++ include/debug/forward_list (working copy) @@ -796,6 +796,13 @@ _S_Is_Beginnest(_BaseIt __it, const _Sequence* __seq) { return _S_Is(__it, __seq); } }; + +#ifndef _GLIBCXX_DEBUG_PEDANTIC + template<class _Tp, class _Alloc> + struct _Insert_range_from_self_is_safe< + std::__debug::forward_list<_Tp, _Alloc> > + { enum { __value = 1 }; }; +#endif } #endif Index: include/debug/string =================================================================== --- include/debug/string (revision 201413) +++ include/debug/string (working copy) @@ -1156,6 +1156,11 @@ typedef basic_string<wchar_t> wstring; #endif + template<typename _CharT, typename _Traits, typename _Allocator> + struct _Insert_range_from_self_is_safe< + __gnu_debug::basic_string<_CharT, _Traits, _Allocator> > + { enum { __value = 1 }; }; + } // namespace __gnu_debug #endif Index: include/debug/macros.h =================================================================== --- include/debug/macros.h (revision 201413) +++ include/debug/macros.h (working copy) @@ -72,11 +72,11 @@ */ #define __glibcxx_check_insert(_Position) \ _GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \ - _M_message(__gnu_debug::__msg_insert_singular) \ + _M_message(__gnu_debug::__msg_insert_singular) \ ._M_sequence(*this, "this") \ ._M_iterator(_Position, #_Position)); \ _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \ - _M_message(__gnu_debug::__msg_insert_different) \ + _M_message(__gnu_debug::__msg_insert_different) \ ._M_sequence(*this, "this") \ ._M_iterator(_Position, #_Position)) @@ -101,15 +101,16 @@ * that it reference the sequence we are inserting into, and that the * iterator range [_First, Last) is a valid (possibly empty) * range. Note that this macro is only valid when the container is a - * _Safe_sequence and the iterator is a _Safe_iterator. - * - * @todo We would like to be able to check for noninterference of - * _Position and the range [_First, _Last), but that can't (in - * general) be done. + * _Safe_sequence and the _Position iterator is a _Safe_iterator. */ #define __glibcxx_check_insert_range(_Position,_First,_Last) \ __glibcxx_check_valid_range(_First,_Last); \ -__glibcxx_check_insert(_Position) +__glibcxx_check_insert(_Position); \ +_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__foreign_iterator(_Position,_First),\ + _M_message(__gnu_debug::__msg_insert_range_from_self)\ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_sequence(*this, "this")) /** Verify that we can insert the values in the iterator range * [_First, _Last) into *this after the iterator _Position. Insertion @@ -126,7 +127,12 @@ */ #define __glibcxx_check_insert_range_after(_Position,_First,_Last) \ __glibcxx_check_valid_range(_First,_Last); \ -__glibcxx_check_insert_after(_Position) +__glibcxx_check_insert_after(_Position); \ +_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__foreign_iterator(_Position,_First),\ + _M_message(__gnu_debug::__msg_insert_range_from_self)\ + ._M_iterator(_First, #_First) \ + ._M_iterator(_Last, #_Last) \ + ._M_sequence(*this, "this")) /** Verify that we can erase the element referenced by the iterator * _Position. We can erase the element if the _Position iterator is @@ -332,7 +338,7 @@ _M_message(__gnu_debug::__msg_valid_load_factor) \ ._M_sequence(*this, "this")) -#define __glibcxx_check_equal_allocs(_Other) \ +#define __glibcxx_check_equal_allocs(_Other) \ _GLIBCXX_DEBUG_VERIFY(this->get_allocator() == _Other.get_allocator(), \ _M_message(__gnu_debug::__msg_equal_allocs) \ ._M_sequence(*this, "this")) Index: include/debug/list =================================================================== --- include/debug/list (revision 201413) +++ include/debug/list (working copy) @@ -791,4 +791,13 @@ } // namespace __debug } // namespace std +#ifndef _GLIBCXX_DEBUG_PEDANTIC +namespace __gnu_debug +{ + template<class _Tp, class _Alloc> + struct _Insert_range_from_self_is_safe<std::__debug::list<_Tp, _Alloc> > + { enum { __value = 1 }; }; +} #endif + +#endif Index: testsuite/util/debug/checks.h =================================================================== --- testsuite/util/debug/checks.h (revision 201413) +++ testsuite/util/debug/checks.h (working copy) @@ -129,7 +129,7 @@ c2.assign(last, first); // Expected failure } - // Check that invalid range of debug !random debug iterators is detected + // Check that invalid range of debug not random iterators is detected template<typename _Tp> void check_assign3() @@ -377,6 +377,34 @@ } template<typename _Tp> + void + check_insert4() + { + bool test __attribute__((unused)) = true; + + typedef _Tp cont_type; + typedef typename cont_type::value_type cont_val_type; + typedef typename CopyableValueType<cont_val_type>::value_type val_type; + typedef std::list<val_type> list_type; + + generate_unique<val_type> gu; + + list_type l; + for (int i = 0; i != 5; ++i) + l.push_back(gu.build()); + VERIFY(l.size() == 5); + + typename list_type::iterator first = l.begin(); ++first; + typename list_type::iterator last = first; ++last; ++last; + + cont_type c1; + InsertRangeHelper<cont_type>::Insert(c1, l.begin(), l.end()); + VERIFY(c1.size() == 5); + + c1.insert(c1.begin(), c1.begin(), c1.end()); // Expected failure. + } + + template<typename _Tp> void use_invalid_iterator() { bool test __attribute__((unused)) = true; Index: testsuite/23_containers/vector/debug/insert5_neg.cc =================================================================== --- testsuite/23_containers/vector/debug/insert5_neg.cc (revision 0) +++ testsuite/23_containers/vector/debug/insert5_neg.cc (revision 0) @@ -0,0 +1,33 @@ +// Copyright (C) 2013 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/>. +// +// { dg-require-debug-mode "" } +// { dg-do run { xfail *-*-* } } + +#include <vector> +#include <debug/checks.h> + +void test01() +{ + __gnu_test::check_insert4<std::vector<int> >(); +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/vector/debug/insert6_neg.cc =================================================================== --- testsuite/23_containers/vector/debug/insert6_neg.cc (revision 0) +++ testsuite/23_containers/vector/debug/insert6_neg.cc (revision 0) @@ -0,0 +1,48 @@ +// Copyright (C) 2013 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/>. +// +// { dg-do run { xfail *-*-* } } + +#include <vector> +#include <debug/vector> +#include <debug/checks.h> + +void test01() +{ + std::vector<bool> v; + __gnu_debug::vector<bool> dv; + for (int i = 0; i != 10; ++i) + { + v.push_back((i % 2) != 0); + dv.push_back((i % 2) == 0); + } + + dv.insert(dv.begin(), v.begin(), v.begin() + 5); + VERIFY( dv.size() == 15 ); +} + +void test02() +{ + __gnu_test::check_insert4<__gnu_debug::vector<bool> >(); +} + +int main() +{ + test01(); + test02(); + return 0; +} Index: testsuite/23_containers/vector/debug/57779_neg.cc =================================================================== --- testsuite/23_containers/vector/debug/57779_neg.cc (revision 0) +++ testsuite/23_containers/vector/debug/57779_neg.cc (revision 0) @@ -0,0 +1,38 @@ +// Copyright (C) 2013 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/>. +// +// { dg-options "-std=gnu++11" } +// { dg-require-debug-mode "" } +// { dg-do run { xfail *-*-* } } + +#include <vector> +#include <debug/checks.h> + +void test01() +{ + std::vector<int> v; + for (int i = 0; i != 10; ++i) + v.push_back(i); + + v.insert(v.begin(), v.data() + 1, v.data() + 5); // Expected failure +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/deque/debug/insert5_neg.cc =================================================================== --- testsuite/23_containers/deque/debug/insert5_neg.cc (revision 0) +++ testsuite/23_containers/deque/debug/insert5_neg.cc (revision 0) @@ -0,0 +1,33 @@ +// Copyright (C) 2013 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/>. +// +// { dg-require-debug-mode "" } +// { dg-do run { xfail *-*-* } } + +#include <deque> +#include <debug/checks.h> + +void test01() +{ + __gnu_test::check_insert4<std::deque<int> >(); +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/list/debug/insert5_neg.cc =================================================================== --- testsuite/23_containers/list/debug/insert5_neg.cc (revision 0) +++ testsuite/23_containers/list/debug/insert5_neg.cc (revision 0) @@ -0,0 +1,34 @@ +// Copyright (C) 2013 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/>. +// +// { dg-require-debug-mode "" } +// { dg-options "-D_GLIBCXX_DEBUG_PEDANTIC" } +// { dg-do run { xfail *-*-* } } + +#include <list> +#include <debug/checks.h> + +void test01() +{ + __gnu_test::check_insert4<std::list<int> >(); +} + +int main() +{ + test01(); + return 0; +} Index: testsuite/23_containers/forward_list/debug/insert_after4_neg.cc =================================================================== --- testsuite/23_containers/forward_list/debug/insert_after4_neg.cc (revision 0) +++ testsuite/23_containers/forward_list/debug/insert_after4_neg.cc (revision 0) @@ -0,0 +1,35 @@ +// Copyright (C) 2013 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/>. +// +// { dg-require-debug-mode "" } +// { dg-options "-std=gnu++11 -D_GLIBCXX_DEBUG_PEDANTIC" } +// { dg-do run { xfail *-*-* } } + +#include <forward_list> +#include <iterator> + +void test01() +{ + std::forward_list<int> fl{ 1, 2, 3 }; + fl.insert_after(fl.before_begin(), fl.begin(), std::next(fl.begin(), 2)); +} + +int main() +{ + test01(); + return 0; +} Index: src/c++11/debug.cc =================================================================== --- src/c++11/debug.cc (revision 201413) +++ src/c++11/debug.cc (working copy) @@ -181,7 +181,8 @@ "attempt to access container with out-of-bounds bucket index %2;," " container only holds %3; buckets", "load factor shall be positive", - "allocators must be equal" + "allocators must be equal", + "attempt to insert with an iterator range [%1.name;, %2.name;) from this container" }; void @@ -695,7 +696,7 @@ } __formatter->_M_format_word(__buf, __bufsize, "@ 0x%p\n", - _M_variant._M_sequence._M_address); + _M_variant._M_iterator._M_sequence); __formatter->_M_print_word(__buf); } __formatter->_M_print_word("}\n"); @@ -808,8 +809,11 @@ if (__length == 0) return; - if ((_M_column + __length < _M_max_length) - || (__length >= _M_max_length && _M_column == 1)) + size_t __visual_length + = __word[__length - 1] == '\n' ? __length - 1 : __length; + if (__visual_length == 0 + || (_M_column + __visual_length < _M_max_length) + || (__visual_length >= _M_max_length && _M_column == 1)) { // If this isn't the first line, indent if (_M_column == 1 && !_M_first_line) @@ -823,17 +827,17 @@ } fprintf(stderr, "%s", __word); - _M_column += __length; if (__word[__length - 1] == '\n') { _M_first_line = false; _M_column = 1; } + else + _M_column += __length; } else { - _M_column = 1; _M_print_word("\n"); _M_print_word(__word); } ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Re: PR 57779 New debug check @ 2013-08-02 2:42 David Edelsohn 2013-08-02 3:02 ` Gabriel Dos Reis 0 siblings, 1 reply; 6+ messages in thread From: David Edelsohn @ 2013-08-02 2:42 UTC (permalink / raw) To: Francois Dumont; +Cc: Paolo Carlini, Jonathan Wakely, libstdc++, GCC Patches This patch broke bootstrap on AIX and probably many other targets. In file included from /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/ debug/safe_sequence.h:34:0, from /nasfarm/edelsohn/src/src/libstdc++-v3/src/c++11/debug.cc: 26: /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/debug/functions.h: In function 'bool __gnu_debug::__foreign_iterator_aux4(const __gnu_debug::_Safe_ite rator<_Iterator, _Sequence>&, _InputIterator, _PointerType1, _PointerType2)': /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/debug/functions.h:189: 6: error: 'addressof' is not a member of 'std' __l(std::addressof(*__other), ^ /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/debug/functions.h:190: 6: error: 'addressof' is not a member of 'std' std::addressof(*(__it._M_get_sequence()->_M_base().begin()))) ^ /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/debug/functions.h:191: 10: error: 'addressof' is not a member of 'std' || __ge(std::addressof(*__other), ^ /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/debug/functions.h:192: 3: error: 'addressof' is not a member of 'std' std::addressof(*(__it._M_get_sequence()->_M_base().end() - 1)) + 1); ^ /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/debug/functions.h: In function 'bool __gnu_debug::__foreign_iterator_aux3(const __gnu_debug::_Safe_ite rator<_Iterator, _Sequence>&, _InputIterator, std::true_type)': /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/debug/functions.h:208: 6: error: '__addressof' is not a member of 'std' if (std::__addressof(*(__it._M_get_sequence()->_M_base().end() - 1)) ^ /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/debug/functions.h:209: 8: error: '__addressof' is not a member of 'std' - std::__addressof(*(__it._M_get_sequence()->_M_base().begin())) ^ /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/debug/functions.h:212: 4: error: 'addressof' is not a member of 'std' std::addressof(*(__it._M_get_sequence()->_M_base().begin())), ^ /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/debug/functions.h:213: 4: error: 'addressof' is not a member of 'std' std::addressof(*__other)); ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Re: PR 57779 New debug check 2013-08-02 2:42 David Edelsohn @ 2013-08-02 3:02 ` Gabriel Dos Reis 2013-08-02 6:54 ` Paolo Carlini 0 siblings, 1 reply; 6+ messages in thread From: Gabriel Dos Reis @ 2013-08-02 3:02 UTC (permalink / raw) To: David Edelsohn Cc: Francois Dumont, Paolo Carlini, Jonathan Wakely, libstdc++, GCC Patches On Thu, Aug 1, 2013 at 9:42 PM, David Edelsohn <dje.gcc@gmail.com> wrote: > This patch broke bootstrap on AIX and probably many other targets. > > In file included from /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/ > debug/safe_sequence.h:34:0, > from /nasfarm/edelsohn/src/src/libstdc++-v3/src/c++11/debug.cc: > 26: > /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/debug/functions.h: In > function 'bool __gnu_debug::__foreign_iterator_aux4(const __gnu_debug::_Safe_ite > rator<_Iterator, _Sequence>&, _InputIterator, _PointerType1, _PointerType2)': > /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/debug/functions.h:189: > 6: error: 'addressof' is not a member of 'std' > __l(std::addressof(*__other), > ^ This is a libstdc++ bug. The file debug/functions.h is missing the inclusion of <memory> By the way, looking at the code, I think the local objects __l and __ge should be declared constexpr. That is not required, but it is good to annotate places where the code is conceptually "pure". -- Gaby ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: PR 57779 New debug check 2013-08-02 3:02 ` Gabriel Dos Reis @ 2013-08-02 6:54 ` Paolo Carlini 2013-08-02 7:37 ` Paolo Carlini 0 siblings, 1 reply; 6+ messages in thread From: Paolo Carlini @ 2013-08-02 6:54 UTC (permalink / raw) To: Gabriel Dos Reis Cc: David Edelsohn, Francois Dumont, Jonathan Wakely, libstdc++, GCC Patches On 08/02/2013 05:02 AM, Gabriel Dos Reis wrote: > On Thu, Aug 1, 2013 at 9:42 PM, David Edelsohn <dje.gcc@gmail.com> wrote: >> This patch broke bootstrap on AIX and probably many other targets. >> >> In file included from /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/ >> debug/safe_sequence.h:34:0, >> from /nasfarm/edelsohn/src/src/libstdc++-v3/src/c++11/debug.cc: >> 26: >> /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/debug/functions.h: In >> function 'bool __gnu_debug::__foreign_iterator_aux4(const __gnu_debug::_Safe_ite >> rator<_Iterator, _Sequence>&, _InputIterator, _PointerType1, _PointerType2)': >> /tmp/20130801/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/debug/functions.h:189: >> 6: error: 'addressof' is not a member of 'std' >> __l(std::addressof(*__other), >> ^ > This is a libstdc++ bug. The file debug/functions.h is missing the inclusion of > <memory> > > By the way, looking at the code, I think the local objects __l and __ge should > be declared constexpr. That is not required, but it is good to annotate places > where the code is conceptually "pure". Thanks. I'll fix these issues momentarily. Paolo. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: PR 57779 New debug check 2013-08-02 6:54 ` Paolo Carlini @ 2013-08-02 7:37 ` Paolo Carlini 2013-08-02 10:37 ` Gabriel Dos Reis 0 siblings, 1 reply; 6+ messages in thread From: Paolo Carlini @ 2013-08-02 7:37 UTC (permalink / raw) To: Gabriel Dos Reis Cc: David Edelsohn, Francois Dumont, Jonathan Wakely, libstdc++, GCC Patches [-- Attachment #1: Type: text/plain, Size: 54 bytes --] ... applied this. Thanks, Paolo. ////////////////// [-- Attachment #2: CL_58049 --] [-- Type: text/plain, Size: 387 bytes --] 2013-08-02 Paolo Carlini <paolo.carlini@oracle.com> PR libstdc++/58049 * include/debug/functions.h: Include <bits/move.h>; minor formatting changes. (__foreign_iterator_aux4): Declare __l and __ge constexpr. * include/debug/safe_iterator.h (_Safe_iterator<>::operator->): Use __addressof. * include/debug/safe_local_iterator.h (_Safe_local_iterator<>:: operator->): Likewise. [-- Attachment #3: patch_58049 --] [-- Type: text/plain, Size: 5217 bytes --] Index: include/debug/functions.h =================================================================== --- include/debug/functions.h (revision 201423) +++ include/debug/functions.h (working copy) @@ -33,6 +33,7 @@ #include <bits/stl_iterator_base_types.h> // for iterator_traits, categories and // _Iter_base #include <bits/cpp_type_traits.h> // for __is_integer +#include <bits/move.h> // for __addressof and addressof #if __cplusplus >= 201103L # include <bits/stl_function.h> // for less and greater_equal # include <type_traits> // for common_type @@ -126,8 +127,8 @@ inline bool __valid_range_aux(const _InputIterator& __first, const _InputIterator& __last, std::__false_type) - { return __valid_range_aux2(__first, __last, - std::__iterator_category(__first)); } + { return __valid_range_aux2(__first, __last, + std::__iterator_category(__first)); } /** Don't know what these iterators are, or if they are even * iterators (we may get an integral type for InputIterator), so @@ -182,15 +183,14 @@ { typedef typename std::common_type<_PointerType1, _PointerType2>::type _PointerType; - std::less<_PointerType> __l; - std::greater_equal<_PointerType> __ge; + constexpr std::less<_PointerType> __l; + constexpr std::greater_equal<_PointerType> __ge; - return - __l(std::addressof(*__other), - std::addressof(*(__it._M_get_sequence()->_M_base().begin()))) - || __ge(std::addressof(*__other), - std::addressof(*(__it._M_get_sequence()->_M_base().end() - 1)) + 1); - + return (__l(std::addressof(*__other), + std::addressof(*(__it._M_get_sequence()->_M_base().begin()))) + || __ge(std::addressof(*__other), + std::addressof(*(__it._M_get_sequence()->_M_base().end() + - 1)) + 1)); } template<typename _Iterator, typename _Sequence, typename _InputIterator> @@ -205,12 +205,13 @@ // past-the-end iterator. if (__it._M_get_sequence()->_M_base().begin() != __it._M_get_sequence()->_M_base().end()) - if (std::__addressof(*(__it._M_get_sequence()->_M_base().end() - 1)) - - std::__addressof(*(__it._M_get_sequence()->_M_base().begin())) + if (std::addressof(*(__it._M_get_sequence()->_M_base().end() - 1)) + - std::addressof(*(__it._M_get_sequence()->_M_base().begin())) == __it._M_get_sequence()->size() - 1) - return __foreign_iterator_aux4(__it, __other, - std::addressof(*(__it._M_get_sequence()->_M_base().begin())), - std::addressof(*__other)); + return (__foreign_iterator_aux4 + (__it, __other, + std::addressof(*(__it._M_get_sequence()->_M_base().begin())), + std::addressof(*__other))); return true; } @@ -232,8 +233,8 @@ { return __it._M_get_sequence() != __other._M_get_sequence(); } #if __cplusplus >= 201103L - /* This overload detects when passing pointers to the contained elements rather - than using iterators. + /* This overload detects when passing pointers to the contained elements + rather than using iterators. */ template<typename _Iterator, typename _Sequence, typename _InputIterator> inline bool @@ -271,10 +272,9 @@ _InputIterator __other, std::__false_type) { - return - _Insert_range_from_self_is_safe<_Sequence>::__value - || __foreign_iterator_aux2(__it, __other, - std::__iterator_category(__it)); + return (_Insert_range_from_self_is_safe<_Sequence>::__value + || __foreign_iterator_aux2(__it, __other, + std::__iterator_category(__it))); } template<typename _Iterator, typename _Sequence, Index: include/debug/safe_iterator.h =================================================================== --- include/debug/safe_iterator.h (revision 201423) +++ include/debug/safe_iterator.h (working copy) @@ -269,7 +269,6 @@ * @brief Iterator dereference. * @pre iterator is dereferenceable * @todo Make this correct w.r.t. iterators that return proxies - * @todo Use addressof() instead of & operator */ pointer operator->() const @@ -277,7 +276,7 @@ _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), _M_message(__msg_bad_deref) ._M_iterator(*this, "this")); - return &*_M_current; + return std::__addressof(*_M_current); } // ------ Input iterator requirements ------ Index: include/debug/safe_local_iterator.h =================================================================== --- include/debug/safe_local_iterator.h (revision 201423) +++ include/debug/safe_local_iterator.h (working copy) @@ -173,7 +173,6 @@ * @brief Iterator dereference. * @pre iterator is dereferenceable * @todo Make this correct w.r.t. iterators that return proxies - * @todo Use addressof() instead of & operator */ pointer operator->() const @@ -181,7 +180,7 @@ _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(), _M_message(__msg_bad_deref) ._M_iterator(*this, "this")); - return &*_M_current; + return std::__addressof(*_M_current); } // ------ Input iterator requirements ------ ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: PR 57779 New debug check 2013-08-02 7:37 ` Paolo Carlini @ 2013-08-02 10:37 ` Gabriel Dos Reis 0 siblings, 0 replies; 6+ messages in thread From: Gabriel Dos Reis @ 2013-08-02 10:37 UTC (permalink / raw) To: Paolo Carlini Cc: David Edelsohn, Francois Dumont, Jonathan Wakely, libstdc++, GCC Patches On Fri, Aug 2, 2013 at 2:36 AM, Paolo Carlini <paolo.carlini@oracle.com> wrote: > ... applied this. thanks. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2013-08-02 10:37 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <51DDC4A0.6020008@gmail.com> [not found] ` <CAH6eHdS-X3B61M3+6NcYmiZ69Q80xda9JUMN7ciZgOC8=yZz8A@mail.gmail.com> [not found] ` <51DEE0A9.9010809@oracle.com> [not found] ` <CAH6eHdQtkAqrDTsSQ5S7xE8P2ABK3JzOAuYNvAB7pxOGWprXSQ@mail.gmail.com> [not found] ` <51DF1291.6040404@gmail.com> [not found] ` <CAH6eHdSdghzQ7NXQutXnVho6a=WVS-Dvnr37Q=myAEWVs2+JSA@mail.gmail.com> [not found] ` <CAH6eHdT=x7djoPSA1Ach9oeENEpz9WH8rGu5jSg4uiEwg+jowA@mail.gmail.com> [not found] ` <51E45AB2.10000@gmail.com> [not found] ` <775842B8-CCCC-4126-9577-AF34711D5123@oracle.com> [not found] ` <CAH6eHdQ9RO8ycEscmaAiJZQqntLk4tHboeK1TjcJydTVxXovHw@mail.gmail.com> [not found] ` <51EEE901.4010107@gmail.com> [not found] ` <51EF9530.3010702@oracle.com> [not found] ` <51F03BF4.6080207@gmail.com> [not found] ` <51F050BC.1060106@oracle.com> 2013-07-31 20:01 ` PR 57779 New debug check François Dumont 2013-07-31 22:40 ` Paolo Carlini 2013-08-01 20:00 ` François Dumont 2013-08-02 2:42 David Edelsohn 2013-08-02 3:02 ` Gabriel Dos Reis 2013-08-02 6:54 ` Paolo Carlini 2013-08-02 7:37 ` Paolo Carlini 2013-08-02 10:37 ` Gabriel Dos Reis
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).