1 // Debugging support implementation -*- C++ -*-
2 
3 // Copyright (C) 2003-2016 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file debug/functions.h
26  *  This file is a GNU debug extension to the Standard C++ Library.
27  */
28 
29 #ifndef _GLIBCXX_DEBUG_FUNCTIONS_H
30 #define _GLIBCXX_DEBUG_FUNCTIONS_H 1
31 
32 #include <bits/move.h>				// for __addressof
33 #include <bits/stl_function.h>			// for less
34 #if __cplusplus >= 201103L
35 # include <type_traits>				// for is_lvalue_reference and
36 						// conditional.
37 #endif
38 
39 #include <debug/helper_functions.h>
40 #include <debug/formatter.h>
41 
42 namespace __gnu_debug
43 {
44   template<typename _Iterator, typename _Sequence>
45     class _Safe_iterator;
46 
47   template<typename _Sequence>
48     struct _Insert_range_from_self_is_safe
49     { enum { __value = 0 }; };
50 
51   template<typename _Sequence>
52     struct _Is_contiguous_sequence : std::__false_type { };
53 
54   // An arbitrary iterator pointer is not singular.
55   inline bool
__check_singular_aux(const void *)56   __check_singular_aux(const void*) { return false; }
57 
58   // We may have an iterator that derives from _Safe_iterator_base but isn't
59   // a _Safe_iterator.
60   template<typename _Iterator>
61     inline bool
__check_singular(const _Iterator & __x)62     __check_singular(const _Iterator& __x)
63     { return __check_singular_aux(std::__addressof(__x)); }
64 
65   /** Non-NULL pointers are nonsingular. */
66   template<typename _Tp>
67     inline bool
__check_singular(const _Tp * __ptr)68     __check_singular(const _Tp* __ptr)
69     { return __ptr == 0; }
70 
71   /** Assume that some arbitrary iterator is dereferenceable, because we
72       can't prove that it isn't. */
73   template<typename _Iterator>
74     inline bool
__check_dereferenceable(const _Iterator &)75     __check_dereferenceable(const _Iterator&)
76     { return true; }
77 
78   /** Non-NULL pointers are dereferenceable. */
79   template<typename _Tp>
80     inline bool
__check_dereferenceable(const _Tp * __ptr)81     __check_dereferenceable(const _Tp* __ptr)
82     { return __ptr; }
83 
84   /* Checks that [first, last) is a valid range, and then returns
85    * __first. This routine is useful when we can't use a separate
86    * assertion statement because, e.g., we are in a constructor.
87   */
88   template<typename _InputIterator>
89     inline _InputIterator
__check_valid_range(const _InputIterator & __first,const _InputIterator & __last)90     __check_valid_range(const _InputIterator& __first,
91 			const _InputIterator& __last
92 			__attribute__((__unused__)))
93     {
94       __glibcxx_check_valid_range(__first, __last);
95       return __first;
96     }
97 
98   /* Handle the case where __other is a pointer to _Sequence::value_type. */
99   template<typename _Iterator, typename _Sequence>
100     inline bool
__foreign_iterator_aux4(const _Safe_iterator<_Iterator,_Sequence> & __it,const typename _Sequence::value_type * __other)101     __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>& __it,
102 			    const typename _Sequence::value_type* __other)
103     {
104       typedef const typename _Sequence::value_type* _PointerType;
105       typedef std::less<_PointerType> _Less;
106 #if __cplusplus >= 201103L
107       constexpr _Less __l{};
108 #else
109       const _Less __l = _Less();
110 #endif
111       const _Sequence* __seq = __it._M_get_sequence();
112       const _PointerType __begin = std::__addressof(*__seq->_M_base().begin());
113       const _PointerType __end = std::__addressof(*(__seq->_M_base().end()-1));
114 
115       // Check whether __other points within the contiguous storage.
116       return __l(__other, __begin) || __l(__end, __other);
117     }
118 
119   /* Fallback overload for when we can't tell, assume it is valid. */
120   template<typename _Iterator, typename _Sequence>
121     inline bool
__foreign_iterator_aux4(const _Safe_iterator<_Iterator,_Sequence> &,...)122     __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>&, ...)
123     { return true; }
124 
125   /* Handle sequences with contiguous storage */
126   template<typename _Iterator, typename _Sequence, typename _InputIterator>
127     inline bool
__foreign_iterator_aux3(const _Safe_iterator<_Iterator,_Sequence> & __it,const _InputIterator & __other,const _InputIterator & __other_end,std::__true_type)128     __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it,
129 			    const _InputIterator& __other,
130 			    const _InputIterator& __other_end,
131 			    std::__true_type)
132     {
133       if (__other == __other_end)
134 	return true;  // inserting nothing is safe even if not foreign iters
135       if (__it._M_get_sequence()->begin() == __it._M_get_sequence()->end())
136 	return true;  // can't be self-inserting if self is empty
137       return __foreign_iterator_aux4(__it, std::__addressof(*__other));
138     }
139 
140   /* Handle non-contiguous containers, assume it is valid. */
141   template<typename _Iterator, typename _Sequence, typename _InputIterator>
142     inline bool
__foreign_iterator_aux3(const _Safe_iterator<_Iterator,_Sequence> &,const _InputIterator &,const _InputIterator &,std::__false_type)143     __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>&,
144 			    const _InputIterator&, const _InputIterator&,
145 			    std::__false_type)
146     { return true; }
147 
148   /** Handle debug iterators from the same type of container. */
149   template<typename _Iterator, typename _Sequence, typename _OtherIterator>
150     inline bool
__foreign_iterator_aux2(const _Safe_iterator<_Iterator,_Sequence> & __it,const _Safe_iterator<_OtherIterator,_Sequence> & __other,const _Safe_iterator<_OtherIterator,_Sequence> &)151     __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it,
152 		const _Safe_iterator<_OtherIterator, _Sequence>& __other,
153 		const _Safe_iterator<_OtherIterator, _Sequence>&)
154     { return __it._M_get_sequence() != __other._M_get_sequence(); }
155 
156   /** Handle debug iterators from different types of container. */
157   template<typename _Iterator, typename _Sequence, typename _OtherIterator,
158 	   typename _OtherSequence>
159     inline bool
__foreign_iterator_aux2(const _Safe_iterator<_Iterator,_Sequence> & __it,const _Safe_iterator<_OtherIterator,_OtherSequence> &,const _Safe_iterator<_OtherIterator,_OtherSequence> &)160     __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it,
161 		const _Safe_iterator<_OtherIterator, _OtherSequence>&,
162 		const _Safe_iterator<_OtherIterator, _OtherSequence>&)
163     { return true; }
164 
165   /* Handle non-debug iterators. */
166   template<typename _Iterator, typename _Sequence, typename _InputIterator>
167     inline bool
__foreign_iterator_aux2(const _Safe_iterator<_Iterator,_Sequence> & __it,const _InputIterator & __other,const _InputIterator & __other_end)168     __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it,
169 			    const _InputIterator& __other,
170 			    const _InputIterator& __other_end)
171     {
172 #if __cplusplus < 201103L
173       typedef _Is_contiguous_sequence<_Sequence> __tag;
174 #else
175       using __lvalref = std::is_lvalue_reference<
176 	typename std::iterator_traits<_InputIterator>::reference>;
177       using __contiguous = _Is_contiguous_sequence<_Sequence>;
178       using __tag = typename std::conditional<__lvalref::value, __contiguous,
179 					      std::__false_type>::type;
180 #endif
181       return __foreign_iterator_aux3(__it, __other, __other_end, __tag());
182     }
183 
184   /* Handle the case where we aren't really inserting a range after all */
185   template<typename _Iterator, typename _Sequence, typename _Integral>
186     inline bool
__foreign_iterator_aux(const _Safe_iterator<_Iterator,_Sequence> &,_Integral,_Integral,std::__true_type)187     __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>&,
188 			   _Integral, _Integral,
189 			   std::__true_type)
190     { return true; }
191 
192   /* Handle all iterators. */
193   template<typename _Iterator, typename _Sequence,
194 	   typename _InputIterator>
195     inline bool
__foreign_iterator_aux(const _Safe_iterator<_Iterator,_Sequence> & __it,_InputIterator __other,_InputIterator __other_end,std::__false_type)196     __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it,
197 			   _InputIterator __other, _InputIterator __other_end,
198 			   std::__false_type)
199     {
200       return _Insert_range_from_self_is_safe<_Sequence>::__value
201 	|| __foreign_iterator_aux2(__it, std::__miter_base(__other),
202 				   std::__miter_base(__other_end));
203     }
204 
205   template<typename _Iterator, typename _Sequence,
206 	   typename _InputIterator>
207     inline bool
__foreign_iterator(const _Safe_iterator<_Iterator,_Sequence> & __it,_InputIterator __other,_InputIterator __other_end)208     __foreign_iterator(const _Safe_iterator<_Iterator, _Sequence>& __it,
209 		       _InputIterator __other, _InputIterator __other_end)
210     {
211       typedef typename std::__is_integer<_InputIterator>::__type _Integral;
212       return __foreign_iterator_aux(__it, __other, __other_end, _Integral());
213     }
214 
215   /** Checks that __s is non-NULL or __n == 0, and then returns __s. */
216   template<typename _CharT, typename _Integer>
217     inline const _CharT*
__check_string(const _CharT * __s,const _Integer & __n)218     __check_string(const _CharT* __s,
219 		   const _Integer& __n __attribute__((__unused__)))
220     {
221 #ifdef _GLIBCXX_DEBUG_PEDANTIC
222       __glibcxx_assert(__s != 0 || __n == 0);
223 #endif
224       return __s;
225     }
226 
227   /** Checks that __s is non-NULL and then returns __s. */
228   template<typename _CharT>
229     inline const _CharT*
__check_string(const _CharT * __s)230     __check_string(const _CharT* __s)
231     {
232 #ifdef _GLIBCXX_DEBUG_PEDANTIC
233       __glibcxx_assert(__s != 0);
234 #endif
235       return __s;
236     }
237 
238   // Can't check if an input iterator sequence is sorted, because we
239   // can't step through the sequence.
240   template<typename _InputIterator>
241     inline bool
__check_sorted_aux(const _InputIterator &,const _InputIterator &,std::input_iterator_tag)242     __check_sorted_aux(const _InputIterator&, const _InputIterator&,
243                        std::input_iterator_tag)
244     { return true; }
245 
246   // Can verify if a forward iterator sequence is in fact sorted using
247   // std::__is_sorted
248   template<typename _ForwardIterator>
249     inline bool
__check_sorted_aux(_ForwardIterator __first,_ForwardIterator __last,std::forward_iterator_tag)250     __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
251                        std::forward_iterator_tag)
252     {
253       if (__first == __last)
254         return true;
255 
256       _ForwardIterator __next = __first;
257       for (++__next; __next != __last; __first = __next, (void)++__next)
258         if (*__next < *__first)
259           return false;
260 
261       return true;
262     }
263 
264   // Can't check if an input iterator sequence is sorted, because we can't step
265   // through the sequence.
266   template<typename _InputIterator, typename _Predicate>
267     inline bool
__check_sorted_aux(const _InputIterator &,const _InputIterator &,_Predicate,std::input_iterator_tag)268     __check_sorted_aux(const _InputIterator&, const _InputIterator&,
269                        _Predicate, std::input_iterator_tag)
270     { return true; }
271 
272   // Can verify if a forward iterator sequence is in fact sorted using
273   // std::__is_sorted
274   template<typename _ForwardIterator, typename _Predicate>
275     inline bool
__check_sorted_aux(_ForwardIterator __first,_ForwardIterator __last,_Predicate __pred,std::forward_iterator_tag)276     __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
277                        _Predicate __pred, std::forward_iterator_tag)
278     {
279       if (__first == __last)
280         return true;
281 
282       _ForwardIterator __next = __first;
283       for (++__next; __next != __last; __first = __next, (void)++__next)
284         if (__pred(*__next, *__first))
285           return false;
286 
287       return true;
288     }
289 
290   // Determine if a sequence is sorted.
291   template<typename _InputIterator>
292     inline bool
__check_sorted(const _InputIterator & __first,const _InputIterator & __last)293     __check_sorted(const _InputIterator& __first, const _InputIterator& __last)
294     {
295       // Verify that the < operator for elements in the sequence is a
296       // StrictWeakOrdering by checking that it is irreflexive.
297       __glibcxx_assert(__first == __last || !(*__first < *__first));
298 
299       return __check_sorted_aux(__first, __last,
300 				std::__iterator_category(__first));
301     }
302 
303   template<typename _InputIterator, typename _Predicate>
304     inline bool
__check_sorted(const _InputIterator & __first,const _InputIterator & __last,_Predicate __pred)305     __check_sorted(const _InputIterator& __first, const _InputIterator& __last,
306                    _Predicate __pred)
307     {
308       // Verify that the predicate is StrictWeakOrdering by checking that it
309       // is irreflexive.
310       __glibcxx_assert(__first == __last || !__pred(*__first, *__first));
311 
312       return __check_sorted_aux(__first, __last, __pred,
313 				std::__iterator_category(__first));
314     }
315 
316   template<typename _InputIterator>
317     inline bool
__check_sorted_set_aux(const _InputIterator & __first,const _InputIterator & __last,std::__true_type)318     __check_sorted_set_aux(const _InputIterator& __first,
319 			   const _InputIterator& __last,
320 			   std::__true_type)
321     { return __check_sorted(__first, __last); }
322 
323   template<typename _InputIterator>
324     inline bool
__check_sorted_set_aux(const _InputIterator &,const _InputIterator &,std::__false_type)325     __check_sorted_set_aux(const _InputIterator&,
326 			   const _InputIterator&,
327 			   std::__false_type)
328     { return true; }
329 
330   template<typename _InputIterator, typename _Predicate>
331     inline bool
__check_sorted_set_aux(const _InputIterator & __first,const _InputIterator & __last,_Predicate __pred,std::__true_type)332     __check_sorted_set_aux(const _InputIterator& __first,
333 			   const _InputIterator& __last,
334 			   _Predicate __pred, std::__true_type)
335     { return __check_sorted(__first, __last, __pred); }
336 
337   template<typename _InputIterator, typename _Predicate>
338     inline bool
__check_sorted_set_aux(const _InputIterator &,const _InputIterator &,_Predicate,std::__false_type)339     __check_sorted_set_aux(const _InputIterator&,
340 			   const _InputIterator&, _Predicate,
341 			   std::__false_type)
342     { return true; }
343 
344   // ... special variant used in std::merge, std::includes, std::set_*.
345   template<typename _InputIterator1, typename _InputIterator2>
346     inline bool
__check_sorted_set(const _InputIterator1 & __first,const _InputIterator1 & __last,const _InputIterator2 &)347     __check_sorted_set(const _InputIterator1& __first,
348 		       const _InputIterator1& __last,
349 		       const _InputIterator2&)
350     {
351       typedef typename std::iterator_traits<_InputIterator1>::value_type
352 	_ValueType1;
353       typedef typename std::iterator_traits<_InputIterator2>::value_type
354 	_ValueType2;
355 
356       typedef typename std::__are_same<_ValueType1, _ValueType2>::__type
357 	_SameType;
358       return __check_sorted_set_aux(__first, __last, _SameType());
359     }
360 
361   template<typename _InputIterator1, typename _InputIterator2,
362 	   typename _Predicate>
363     inline bool
__check_sorted_set(const _InputIterator1 & __first,const _InputIterator1 & __last,const _InputIterator2 &,_Predicate __pred)364     __check_sorted_set(const _InputIterator1& __first,
365 		       const _InputIterator1& __last,
366 		       const _InputIterator2&, _Predicate __pred)
367     {
368       typedef typename std::iterator_traits<_InputIterator1>::value_type
369 	_ValueType1;
370       typedef typename std::iterator_traits<_InputIterator2>::value_type
371 	_ValueType2;
372 
373       typedef typename std::__are_same<_ValueType1, _ValueType2>::__type
374 	_SameType;
375       return __check_sorted_set_aux(__first, __last, __pred, _SameType());
376    }
377 
378   // _GLIBCXX_RESOLVE_LIB_DEFECTS
379   // 270. Binary search requirements overly strict
380   // Determine if a sequence is partitioned w.r.t. this element.
381   template<typename _ForwardIterator, typename _Tp>
382     inline bool
__check_partitioned_lower(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value)383     __check_partitioned_lower(_ForwardIterator __first,
384 			      _ForwardIterator __last, const _Tp& __value)
385     {
386       while (__first != __last && *__first < __value)
387 	++__first;
388       if (__first != __last)
389 	{
390 	  ++__first;
391 	  while (__first != __last && !(*__first < __value))
392 	    ++__first;
393 	}
394       return __first == __last;
395     }
396 
397   template<typename _ForwardIterator, typename _Tp>
398     inline bool
__check_partitioned_upper(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value)399     __check_partitioned_upper(_ForwardIterator __first,
400 			      _ForwardIterator __last, const _Tp& __value)
401     {
402       while (__first != __last && !(__value < *__first))
403 	++__first;
404       if (__first != __last)
405 	{
406 	  ++__first;
407 	  while (__first != __last && __value < *__first)
408 	    ++__first;
409 	}
410       return __first == __last;
411     }
412 
413   // Determine if a sequence is partitioned w.r.t. this element.
414   template<typename _ForwardIterator, typename _Tp, typename _Pred>
415     inline bool
__check_partitioned_lower(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value,_Pred __pred)416     __check_partitioned_lower(_ForwardIterator __first,
417 			      _ForwardIterator __last, const _Tp& __value,
418 			      _Pred __pred)
419     {
420       while (__first != __last && bool(__pred(*__first, __value)))
421 	++__first;
422       if (__first != __last)
423 	{
424 	  ++__first;
425 	  while (__first != __last && !bool(__pred(*__first, __value)))
426 	    ++__first;
427 	}
428       return __first == __last;
429     }
430 
431   template<typename _ForwardIterator, typename _Tp, typename _Pred>
432     inline bool
__check_partitioned_upper(_ForwardIterator __first,_ForwardIterator __last,const _Tp & __value,_Pred __pred)433     __check_partitioned_upper(_ForwardIterator __first,
434 			      _ForwardIterator __last, const _Tp& __value,
435 			      _Pred __pred)
436     {
437       while (__first != __last && !bool(__pred(__value, *__first)))
438 	++__first;
439       if (__first != __last)
440 	{
441 	  ++__first;
442 	  while (__first != __last && bool(__pred(__value, *__first)))
443 	    ++__first;
444 	}
445       return __first == __last;
446     }
447 
448 #if __cplusplus >= 201103L
449   struct _Irreflexive_checker
450   {
451     template<typename _It>
452       static typename std::iterator_traits<_It>::reference
453       __deref();
454 
455     template<typename _It,
456 	     typename = decltype(__deref<_It>() < __deref<_It>())>
457       static bool
_S_is_valid_Irreflexive_checker458       _S_is_valid(_It __it)
459       { return !(*__it < *__it); }
460 
461     // Fallback method if operator doesn't exist.
462     template<typename... _Args>
463       static bool
_S_is_valid_Irreflexive_checker464       _S_is_valid(_Args...)
465       { return true; }
466 
467     template<typename _It, typename _Pred, typename
468 	= decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))>
469       static bool
_S_is_valid_pred_Irreflexive_checker470       _S_is_valid_pred(_It __it, _Pred __pred)
471       { return !__pred(*__it, *__it); }
472 
473     // Fallback method if predicate can't be invoked.
474     template<typename... _Args>
475       static bool
_S_is_valid_pred_Irreflexive_checker476       _S_is_valid_pred(_Args...)
477       { return true; }
478   };
479 
480   template<typename _Iterator>
481     inline bool
__is_irreflexive(_Iterator __it)482     __is_irreflexive(_Iterator __it)
483     { return _Irreflexive_checker::_S_is_valid(__it); }
484 
485   template<typename _Iterator, typename _Pred>
486     inline bool
__is_irreflexive_pred(_Iterator __it,_Pred __pred)487     __is_irreflexive_pred(_Iterator __it, _Pred __pred)
488     { return _Irreflexive_checker::_S_is_valid_pred(__it, __pred); }
489 #endif
490 
491 } // namespace __gnu_debug
492 
493 #endif
494