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)