https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103233
--- Comment #3 from alx.manpages at gmail dot com --- Hi Jonathan, On 11/14/21 15:57, redi at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103233 > > Jonathan Wakely <redi at gcc dot gnu.org> changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > Status|UNCONFIRMED |WAITING > Last reconfirmed| |2021-11-14 > Ever confirmed|0 |1 > > --- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> --- > (In reply to Alejandro Colomar from comment #0) >> 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). > > The analyzer doesn't support C++ properly yet, and is completely wrong here. > See below. > > > >> Another is that I'm seeing the error while compiling user code (my library): >> <https://github.com/alejandro-colomar/libalx> > > What error? Please provide the code to reproduce the problem, not just a URL, > see https://gcc.gnu.org/bugs Well, not an error, but a warning (I transformed it into an error with -Werror). The error/warning that I referred to was the one I copied entirely (including the command to produce it). The case that I reported was compiling an already preprocessed file. Since it was a big temporary file (and probably less readable than the source), I didn't share it. I simplified the file, and compiled it directly, to simplify reproducing it: $ cat sys_warning.cxx /****************************************************************************** * Copyright (c) 2018 by Alejandro Colomar <alx.manpa...@gmail.com> * SPDX-License-Identifier: GPL-2.0-only ******************************************************************************/ #include <stddef.h> #include <vector> #include <opencv2/calib3d.hpp> #include <opencv2/core/base.hpp> #include <opencv2/core/mat.hpp> #include <opencv2/features2d.hpp> #include <opencv2/imgproc.hpp> static constexpr int MAX_FEATURES = 50000; static constexpr double GOOD_MATCH_P = 0.25; [[gnu::nonnull(1, 2)]] void orb_align(const class cv::Mat *ref, class cv::Mat *img, class cv::Mat *img_matches); void orb_align(const class cv::Mat *ref, class cv::Mat *img, class cv::Mat *img_matches) { class std::vector <class cv::KeyPoint> keypoints_0; class std::vector <class cv::KeyPoint> keypoints_1; class cv::Mat descriptors_0; class cv::Mat descriptors_1; struct cv::Ptr <class cv::Feature2D> orb; class std::vector <class cv::DMatch> matches; struct cv::Ptr <class cv::DescriptorMatcher> matcher; ptrdiff_t good_matches; class std::vector <class cv::Point_ <float>> points_0; class std::vector <class cv::Point_ <float>> points_1; ptrdiff_t size; class cv::Mat img_hg; class cv::Mat img_align; /* Detect ORB features & compute descriptors */ orb = cv::ORB::create(MAX_FEATURES, 1.2f, 8, 31, 0, 2, cv::ORB::HARRIS_SCORE, 31, 20); orb->detectAndCompute(*ref, cv::Mat(), keypoints_0, descriptors_0, false); orb->detectAndCompute(*img, cv::Mat(), keypoints_1, descriptors_1, false); /* Match structures */ matcher = cv::DescriptorMatcher::create("BruteForce-Hamming"); matcher->match(descriptors_1, descriptors_0, matches, cv::Mat()); /* Sort matches by score */ std::sort(matches.begin(), matches.end()); /* Remove not so good matches */ good_matches = GOOD_MATCH_P * matches.size(); matches.erase(matches.begin() + good_matches, matches.end()); /* Draw top matches */ if (img_matches) cv::drawMatches(*img, keypoints_1, *ref, keypoints_0, matches, *img_matches, cv::Scalar::all(-1), cv::Scalar::all(-1), std::vector<char>(), cv::DrawMatchesFlags::DEFAULT); /* Extract location of good matches */ size = matches.size(); for (ptrdiff_t i = 0; i < size; i++) { points_1.push_back(keypoints_1[matches[i].queryIdx].pt); points_0.push_back(keypoints_0[matches[i].trainIdx].pt); } /* Find homography */ img_hg = cv::findHomography(points_1, points_0, cv::RANSAC, 3, cv::noArray(), 2000, 0.995); /* Use homography to warp image */ cv::warpPerspective(*img, img_align, img_hg, ref->size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar()); /* Write img_align into img */ *img = img_align; img_align.release(); } $ c++ -D _GNU_SOURCE -D _POSIX_C_SOURCE=200809L -O3 -Wall -Wextra -Winvalid-pch -fno-common -fpic -isystem/usr/include/opencv4 -fanalyzer -std=gnu++20 -Wno-vla -S sys_warning.cxx You'll need libopencv-dev (or equivalent) to compile. > > >> |/usr/include/c++/11/bits/stl_vector.h:346:25: >> | 346 | return __n != 0 ? _Tr::allocate(_M_impl, __n) : >> pointer(); >> | | >> ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> | | | >> | | (7) following 'false' branch... > > This cannot happen. The length is this->size() + 1 and we already checked for > overflow, so it is guaranteed to be a positive integer. > > >> |...... >> | 127 | return static_cast<_Tp*>(::operator new(__n * >> sizeof(_Tp))); >> | | >> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> | | | >> | | (12) >> ...to here >> | | (13) this >> call could return NULL > > > This is nonsense, operator new(size_t) cannot return null. Okay, then I hope this helps improving fanalyzer :) Regards, Alex