https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103233
Bug ID: 103233 Summary: Warning from system libraries in user code: CWE-476 -Werror=analyzer-null-dereference Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: colomar.6.4.3 at gmail dot com Target Milestone: --- There are two problems here: One is a dereference of a NULL pointer in the standard C++ library code (at least that's what -fanalyzer reports). Another is that I'm seeing the error while compiling user code (my library): <https://github.com/alejandro-colomar/libalx> c++ -D _GNU_SOURCE -D _POSIX_C_SOURCE=200809L -D SYSCONFDIR_='"/usr/local/etc/alx"' -O3 -Wall -Wextra -Winvalid-pch -fno-common -Werror -fpic -isystem/usr/local/include -D_GNU_SOURCE -D_POSIX_C_SOURCE=200809L -isystem/usr/include/opencv4 -isystem/usr/local/include -D_GNU_SOURCE -D_POSIX_C_SOURCE=200809L -isystem/usr/local/include -D_GNU_SOURCE -D_POSIX_C_SOURCE=200809L -fanalyzer -std=gnu++20 -Wno-vla -I /home/alx/src/alx/libalx/include -fpreprocessed -S -o /home/alx/src/alx/libalx/tmp/alx/cv/features2d/orb.cxx.s /home/alx/src/alx/libalx/tmp/alx/cv/features2d/orb.cxx.i In member function 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': cc1plus: error: dereference of NULL '__cur' [CWE-476] [-Werror=analyzer-null-dereference] 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': events 1-2 | |/usr/include/c++/11/bits/vector.tcc:426:7: | 426 | vector<_Tp, _Alloc>:: | | ^~~~~~~~~~~~~~~~~~~ | | | | | (1) entry to 'std::vector<cv::Point_<float> >::_M_realloc_insert<const cv::Point_<float>&>' |...... | 436 | _M_check_len(size_type(1), "vector::_M_realloc_insert"); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (2) calling 'std::vector<cv::Point_<float> >::_M_check_len' from 'std::vector<cv::Point_<float> >::_M_realloc_insert<const cv::Point_<float>&>' | +--> 'std::vector<_Tp, _Alloc>::size_type std::vector<_Tp, _Alloc>::_M_check_len(std::vector<_Tp, _Alloc>::size_type, const char*) const [with _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': events 3-5 | |/usr/include/c++/11/bits/stl_vector.h:1756:7: | 1756 | _M_check_len(size_type __n, const char* __s) const | | ^~~~~~~~~~~~ | | | | | (3) entry to 'std::vector<cv::Point_<float> >::_M_check_len' | 1757 | { | 1758 | if (max_size() - size() < __n) | | ~~ | | | | | (4) following 'false' branch... |...... | 1761 | const size_type __len = size() + (std::max)(size(), __n); | | ~~~~~~ | | | | | (5) ...to here | <------+ | 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': event 6 | |/usr/include/c++/11/bits/vector.tcc:436:21: | 436 | _M_check_len(size_type(1), "vector::_M_realloc_insert"); | | ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (6) returning to 'std::vector<cv::Point_<float> >::_M_realloc_insert<const cv::Point_<float>&>' from 'std::vector<cv::Point_<float> >::_M_check_len' | 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': event 7 | |/usr/include/c++/11/bits/stl_vector.h:346:25: | 346 | return __n != 0 ? _Tr::allocate(_M_impl, __n) : pointer(); | | ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (7) following 'false' branch... | 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': event 8 | |/usr/include/c++/11/bits/vector.tcc:450:48: | 450 | __new_start + __elems_before, | | ~~~~~~~~~~~~^~~~~~~~~~~~~~~~ | | | | | (8) ...to here | 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': event 9 | |/usr/include/c++/11/bits/stl_uninitialized.h:1031:22: | 1031 | for (; __first != __last; ++__first, (void)++__cur) | | ~~~~~~~~^~~~~~~~~ | | | | | (9) following 'true' branch (when '__first != <unknown>')... | 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': event 10 | |/usr/include/c++/11/bits/stl_construct.h:88:9: | 88 | __location->~_Tp(); | | ^~~~~~~~~~ | | | | | (10) ...to here | 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': event 11 | |cc1plus: | (11): dereference of NULL '__cur' | cc1plus: error: dereference of possibly-NULL '__cur' [CWE-690] [-Werror=analyzer-possible-null-dereference] 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': events 1-2 | |/usr/include/c++/11/bits/vector.tcc:426:7: | 426 | vector<_Tp, _Alloc>:: | | ^~~~~~~~~~~~~~~~~~~ | | | | | (1) entry to 'std::vector<cv::Point_<float> >::_M_realloc_insert<const cv::Point_<float>&>' |...... | 436 | _M_check_len(size_type(1), "vector::_M_realloc_insert"); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (2) calling 'std::vector<cv::Point_<float> >::_M_check_len' from 'std::vector<cv::Point_<float> >::_M_realloc_insert<const cv::Point_<float>&>' | +--> 'std::vector<_Tp, _Alloc>::size_type std::vector<_Tp, _Alloc>::_M_check_len(std::vector<_Tp, _Alloc>::size_type, const char*) const [with _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': events 3-5 | |/usr/include/c++/11/bits/stl_vector.h:1756:7: | 1756 | _M_check_len(size_type __n, const char* __s) const | | ^~~~~~~~~~~~ | | | | | (3) entry to 'std::vector<cv::Point_<float> >::_M_check_len' | 1757 | { | 1758 | if (max_size() - size() < __n) | | ~~ | | | | | (4) following 'false' branch... |...... | 1761 | const size_type __len = size() + (std::max)(size(), __n); | | ~~~~~~ | | | | | (5) ...to here | <------+ | 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': event 6 | |/usr/include/c++/11/bits/vector.tcc:436:21: | 436 | _M_check_len(size_type(1), "vector::_M_realloc_insert"); | | ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (6) returning to 'std::vector<cv::Point_<float> >::_M_realloc_insert<const cv::Point_<float>&>' from 'std::vector<cv::Point_<float> >::_M_check_len' | 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': events 7-8 | |/usr/include/c++/11/bits/stl_vector.h:346:25: | 346 | return __n != 0 ? _Tr::allocate(_M_impl, __n) : pointer(); | | ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | | | (8) ...to here | | (7) following 'true' branch... | 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': event 9 | |/usr/include/c++/11/bits/allocator.h:201:47: | 201 | return __allocator_base<_Tp>::allocate(__n, 0); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~ | | | | | (9) calling '__gnu_cxx::new_allocator<cv::Point_<float> >::allocate' from 'std::vector<cv::Point_<float> >::_M_realloc_insert<const cv::Point_<float>&>' | +--> '_Tp* __gnu_cxx::new_allocator<_Tp>::allocate(__gnu_cxx::new_allocator<_Tp>::size_type, const void*) [with _Tp = cv::Point_<float>]': events 10-13 | |/usr/include/c++/11/ext/new_allocator.h:103:7: | 103 | allocate(size_type __n, const void* = static_cast<const void*>(0)) | | ^~~~~~~~ | | | | | (10) entry to '__gnu_cxx::new_allocator<cv::Point_<float> >::allocate' |...... | 111 | if (__builtin_expect(__n > this->_M_max_size(), false)) | | ~~ | | | | | (11) following 'false' branch... |...... | 127 | return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (12) ...to here | | (13) this call could return NULL | <------+ | 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': event 14 | |/usr/include/c++/11/bits/allocator.h:201:47: | 201 | return __allocator_base<_Tp>::allocate(__n, 0); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~ | | | | | (14) returning to 'std::vector<cv::Point_<float> >::_M_realloc_insert<const cv::Point_<float>&>' from '__gnu_cxx::new_allocator<cv::Point_<float> >::allocate' | 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': event 15 | |/usr/include/c++/11/bits/stl_uninitialized.h:1031:22: | 1031 | for (; __first != __last; ++__first, (void)++__cur) | | ~~~~~~~~^~~~~~~~~ | | | | | (15) following 'true' branch (when '__first != <unknown>')... | 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': event 16 | |/usr/include/c++/11/bits/stl_construct.h:88:9: | 88 | __location->~_Tp(); | | ^~~~~~~~~~ | | | | | (16) ...to here | 'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_<float>&}; _Tp = cv::Point_<float>; _Alloc = std::allocator<cv::Point_<float> >]': event 17 | |cc1plus: | (17): '__cur' could be NULL: unchecked value from (13) | cc1plus: all warnings being treated as errors