libstdc++: Improve _GLIBCXX_DEBUG __valid_range check
authorFrançois Dumont <fdumont@gcc.gnu.org>
Sun, 24 Nov 2019 17:09:44 +0000 (17:09 +0000)
committerFrançois Dumont <fdumont@gcc.gnu.org>
Sun, 24 Nov 2019 17:09:44 +0000 (17:09 +0000)
Adds iterator singular check within the valid range check.

* include/debug/functions.h: Remove <bits/move.h> include.
(__check_singular_aux, __check_singular): Move...
* include/debug/helper_functions.h:
(__check_singular_aux, __check_singular): ...here.
(__valid_range_aux): Adapt to use latter.
Add <bits/move.h> include.
* testsuite/25_algorithms/copy/debug/2_neg.cc: New.

From-SVN: r278658

libstdc++-v3/ChangeLog
libstdc++-v3/include/debug/functions.h
libstdc++-v3/include/debug/helper_functions.h
libstdc++-v3/testsuite/25_algorithms/copy/debug/2_neg.cc [new file with mode: 0644]

index ec9039d..a479a12 100644 (file)
@@ -1,3 +1,12 @@
+2019-11-24  François Dumont  <fdumont@gcc.gnu.org>
+
+       * include/debug/functions.h: Remove <bits/move.h> include.
+       (__check_singular_aux, __check_singular): Move...
+       * include/debug/helper_functions.h:
+       (__check_singular_aux, __check_singular): ...here.
+       (__valid_range_aux): Adapt to use latter.
+       * testsuite/25_algorithms/copy/debug/2_neg.cc: New.
+
 2019-11-20  Janne Blomqvist  <jb@gcc.gnu.org>
 
        * doc/html/api.html: Use https for gcc.gnu.org.
        * doc/xml/manual/codecvt.xml: Switch pubs.opengroup.org to https.
        * doc/xml/manual/locale.xml (LC_ALL): Ditto.
        * doc/xml/manual/messages.xml: Ditto.
-       
+
 2019-10-26  John David Anglin  <danglin@gcc.gnu.org>
 
        * config/abi/post/hppa-linux-gnu/baseline_symbols.txt: Update.
        pubs.opengroup.org to https.
 
 2019-10-25  Gerald Pfeifer  <gerald@pfeifer.com>
-       
+
        * doc/xml/gnu/gpl-3.0.xml: Switch www.gnu.org to https.
 
 2019-09-09  Edward Smith-Rowland  <3dw4rd@verizon.net>
        PSTL backend if no TBB present.
        * testsuite/utils/pstl/test_utils.h: Remove check for
        _PSTL_USE_PAR_POLICIES
-       
+
 2019-06-07  Jonathan Wakely  <jwakely@redhat.com>
 
        * testsuite/24_iterators/container_access.cc: Move dg-options before
        Document PSTL linker flags
 
        * doc/xml/manual/using.xml: Add PSTL linker flags to table 3.1.
-       
+
 2019-04-23  Jonathan Wakely  <jwakely@redhat.com>
 
        * include/std/variant (__detail::__variant::_Traits): Make
 
        * include/bits/c++config: Remove explicit PSTL configuration
        macros and use definitions from <pstl/pstl_config.h>.
-       
+
 2019-04-20  Thomas Rodgers <trodgers@redhat.com>
 
        Cleanup algorithm implementations
        (equal): Qualify call to std::equal().
        (partial_sort): Forward execution policy.
        (inplace_merge): Forward execution policy.
-       
+
 2019-04-19  Thomas Rodgers <trodgers@redhat.com>
-       
+
        Improve implementation of parallel equal()
        * include/pstl/algorithm_impl.h
        (__internal::__brick_equal): use "4 iterator" version of
        * include/pstl/glue_algorithm_impl.h
        (std::equal): dispatch to "4 iterator" version of
        __internal::__pattern_equal().
-       
+
 2019-04-17  Jonathan Wakely  <jwakely@redhat.com>
 
        PR libstdc++/90105
        * testsuite/20_util/optional/observers/4.cc: Likewise.
 
 2019-04-12  Thomas Rodgers  <trodgers@redhat.com>
-       
+
        * include/pstl/algorithm_impl.h: Uglify identfiers.
        * include/pstl/numeric_impl.h:  Uglify identfiers.
        * include/pstl/parallel_backend_tbb.h: Uglify identfiers.
        avoid -Wconversion warnings.
 
 2019-03-21  Thomas Rodgers  <trodgers@redhat.com>
-       
+
        * include/Makefile.am (std_header): Add ${std_srcdir}/execution.
        (pstl_srcdir, pstl_builddir, pstl_headers): New variables.
        (allstamped): Add stamp-pstl.
index 8c385b8..12df745 100644 (file)
@@ -29,7 +29,6 @@
 #ifndef _GLIBCXX_DEBUG_FUNCTIONS_H
 #define _GLIBCXX_DEBUG_FUNCTIONS_H 1
 
-#include <bits/move.h>         // for __addressof
 #include <bits/stl_function.h> // for less
 
 #if __cplusplus >= 201103L
@@ -49,23 +48,6 @@ namespace __gnu_debug
   template<typename _Sequence>
     struct _Is_contiguous_sequence : std::__false_type { };
 
-  // An arbitrary iterator pointer is not singular.
-  inline bool
-  __check_singular_aux(const void*) { return false; }
-
-  // We may have an iterator that derives from _Safe_iterator_base but isn't
-  // a _Safe_iterator.
-  template<typename _Iterator>
-    inline bool
-    __check_singular(const _Iterator& __x)
-    { return __check_singular_aux(std::__addressof(__x)); }
-
-  /** Non-NULL pointers are nonsingular. */
-  template<typename _Tp>
-    inline bool
-    __check_singular(const _Tp* __ptr)
-    { return __ptr == 0; }
-
   /* Checks that [first, last) is a valid range, and then returns
    * __first. This routine is useful when we can't use a separate
    * assertion statement because, e.g., we are in a constructor.
index c3e7478..ac93ee0 100644 (file)
@@ -29,6 +29,7 @@
 #ifndef _GLIBCXX_DEBUG_HELPER_FUNCTIONS_H
 #define _GLIBCXX_DEBUG_HELPER_FUNCTIONS_H 1
 
+#include <bits/move.h>                         // for __addressof
 #include <bits/stl_iterator_base_types.h>      // for iterator_traits,
                                                // categories and _Iter_base
 #include <bits/cpp_type_traits.h>              // for __is_integer
@@ -112,6 +113,23 @@ namespace __gnu_debug
     __get_distance(_Iterator __lhs, _Iterator __rhs)
     { return __get_distance(__lhs, __rhs, std::__iterator_category(__lhs)); }
 
+  // An arbitrary iterator pointer is not singular.
+  inline bool
+  __check_singular_aux(const void*) { return false; }
+
+  // We may have an iterator that derives from _Safe_iterator_base but isn't
+  // a _Safe_iterator.
+  template<typename _Iterator>
+    inline bool
+    __check_singular(_Iterator const& __x)
+    { return __check_singular_aux(std::__addressof(__x)); }
+
+  /** Non-NULL pointers are nonsingular. */
+  template<typename _Tp>
+    inline bool
+    __check_singular(_Tp* const& __ptr)
+    { return __ptr == 0; }
+
   /** We say that integral types for a valid range, and defer to other
    *  routines to realize what to do with integral types instead of
    *  iterators.
@@ -138,14 +156,21 @@ namespace __gnu_debug
     inline bool
     __valid_range_aux(_InputIterator __first, _InputIterator __last,
                      std::input_iterator_tag)
-    { return true; }
+    {
+      return __first == __last
+       || (!__check_singular(__first) && !__check_singular(__last));
+    }
 
   template<typename _InputIterator>
     _GLIBCXX_CONSTEXPR
     inline bool
     __valid_range_aux(_InputIterator __first, _InputIterator __last,
                      std::random_access_iterator_tag)
-    { return __first <= __last; }
+    {
+      return
+       __valid_range_aux(__first, __last, std::input_iterator_tag{})
+       && __first <= __last;
+    }
 
   /** We have iterators, so figure out what kind of iterators they are
    *  to see if we can check the range ahead of time.
@@ -167,6 +192,9 @@ namespace __gnu_debug
                      typename _Distance_traits<_InputIterator>::__type& __dist,
                      std::__false_type)
     {
+      if (!__valid_range_aux(__first, __last, std::input_iterator_tag{}))
+       return false;
+
       __dist = __get_distance(__first, __last);
       switch (__dist.second)
        {
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/debug/2_neg.cc b/libstdc++-v3/testsuite/25_algorithms/copy/debug/2_neg.cc
new file mode 100644 (file)
index 0000000..8bbf873
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (C) 2019 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/>.
+
+// 25.2.1 [lib.alg.copy] Copy.
+
+// { dg-do run { xfail *-*-* } }
+// { dg-require-debug-mode "" }
+
+#include <algorithm>
+
+void
+test01()
+{
+  int arr[] = { 0, 1, 2, 3, 4 };
+  std::copy((int*)0, arr + 5, arr);
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}