This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libstdc++/84256] New: Use object size checking built-ins in libstdc++


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84256

            Bug ID: 84256
           Summary: Use object size checking built-ins in libstdc++
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

#include <vector>

int main()
{
  int a[2] = { };
  std::vector<int> v(a, a+3);
}

This gets caught by AddressSanitizer, but it would be possible to warn at
compile-time by using __builtin_object_size, with something like

--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -71,6 +71,15 @@ __sanitizer_annotate_contiguous_container(const void*, const
void*,
                                          const void*, const void*);
 #endif

+namespace __gnu_debug
+{
+  void
+  __bad_iterator_range()
+  __attribute__((__warning__("invalid end iterator")));
+
+  inline void __bad_iterator_range() { }
+}
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -543,7 +552,16 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        vector(_InputIterator __first, _InputIterator __last,
               const allocator_type& __a = allocator_type())
        : _Base(__a)
-       { _M_initialize_dispatch(__first, __last, __false_type()); }
+       {
+         if _GLIBCXX17_CONSTEXPR (is_pointer<_InputIterator>::value)
+           {
+             const size_t __len = __builtin_object_size(__first, 1);
+             using _Vp = typename iterator_traits<_InputIterator>::value_type;
+             if (__len < (size_t)std::distance(__last - __first) *
sizeof(_Vp))
+               __gnu_debug::__bad_iterator_range();
+           }
+         _M_initialize_dispatch(__first, __last, __false_type());
+       }
 #else
       template<typename _InputIterator>
        vector(_InputIterator __first, _InputIterator __last,


We could do this in every function that takes a pair of iterators to read from
or write to, although maybe only when _GLIBCXX_ASSERTIONS is defined.

We could also use the checking versions of __builtin_memmove etc. in
<bits/stl_algobase.h> (although only when __memcpy_chk is available, and again
probably onyl when ASSERTIONS are enabled).

https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html

(This is the general case of PR 54924 which is specific to std::basic_string)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]