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

            Bug ID: 106434
           Summary: Spurious -Wnull-dereference when using
                    std::unique_copy()
           Product: gcc
           Version: 12.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: vz-gcc at zeitlins dot org
  Target Milestone: ---

The following simple example shows the problem with g++ 12, which didn't exist
with the previous versions:

% g++ -v
Using built-in specs.
COLLECT_GCC=/usr/bin/g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/12/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 12.1.0-7'
--with-bugurl=file:///usr/share/doc/gcc-12/README.Bugs
--enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr
--with-gcc-major-version-only --program-suffix=-12
--program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug
--enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new
--enable-gnu-unique-object --disable-vtable-verify --enable-plugin
--enable-default-pie --with-system-zlib --enable-libphobos-checking=release
--with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch
--disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64
--with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic
--enable-offload-targets=nvptx-none=/build/gcc-12-aYRw0H/gcc-12-12.1.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-12-aYRw0H/gcc-12-12.1.0/debian/tmp-gcn/usr
--enable-offload-defaulted --without-cuda-driver --enable-checking=release
--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 12.1.0 (Debian 12.1.0-7)
% cat unique_copy.cpp
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>

std::vector<std::string> const& parms();

int main() {
    std::vector<std::string> all;

    for(auto const& i : parms()) {
        all.push_back(i);
    }

    std::vector<std::string> unique;
    std::insert_iterator iin(unique, unique.begin()); // EXCHANGE THESE LINES
    std::sort(all.begin(), all.end());                // TO SUPPRESS THE
WARNING
    std::unique_copy(all.begin(), all.end(), iin);
}
% g++ -std=c++20 -c -O2 -Wnull-dereference unique_copy.cpp
In file included from /usr/include/c++/12/string:53,
                 from /usr/include/c++/12/bits/locale_classes.h:40,
                 from /usr/include/c++/12/bits/ios_base.h:41,
                 from /usr/include/c++/12/streambuf:41,
                 from /usr/include/c++/12/bits/streambuf_iterator.h:35,
                 from /usr/include/c++/12/iterator:66,
                 from unique_copy.cpp:2:
In constructor ‘constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>::_Alloc_hider::_Alloc_hider(std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>::pointer, _Alloc&&) [with _CharT = char; _Traits =
std::char_traits<char>; _Alloc = std::allocator<char>]’,
    inlined from ‘constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>::basic_string(const std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc =
std::allocator<char> ’ at /usr/include/c++/12/bits/basic_string.h:540:9,
    inlined from ‘constexpr decltype (::new(void*(0)) _Tp)
std::construct_at(_Tp*, _Args&& ...) [with _Tp = __cxx11::basic_string<char>;
_Args = {const __cxx11::basic_string<char, char_traits<char>, allocator<char>
>&}]’ at /usr/include/c++/12/bits/stl_construct.h:97:14,
    inlined from ‘static constexpr void
std::allocator_traits<std::allocator<_CharT> >::construct(allocator_type&,
_Up*, _Args&& ...) [with _Up = std::__cxx11::basic_string<char>; _Args = {const
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>
>&}; _Tp = std::__cxx11::basic_string<char>]’ at
/usr/include/c++/12/bits/alloc_traits.h:518:21,
    inlined from ‘constexpr std::vector<_Tp, _Alloc>::iterator std::vector<_Tp,
_Alloc>::insert(const_iterator, const value_type&) [with _Tp =
std::__cxx11::basic_string<char>; _Alloc =
std::allocator<std::__cxx11::basic_string<char> >]’ at
/usr/include/c++/12/bits/vector.tcc:145:30,
    inlined from ‘constexpr std::insert_iterator<_Container>&
std::insert_iterator<_Container>::operator=(const typename
_Container::value_type&) [with _Container =
std::vector<std::__cxx11::basic_string<char> >]’ at
/usr/include/c++/12/bits/stl_iterator.h:964:26,
    inlined from ‘constexpr _OutputIterator
std::__unique_copy(_ForwardIterator, _ForwardIterator, _OutputIterator,
_BinaryPredicate, forward_iterator_tag, output_iterator_tag) [with
_ForwardIterator = __gnu_cxx::__normal_iterator<__cxx11::basic_string<char>*,
vector<__cxx11::basic_string<char> > >; _OutputIterator =
insert_iterator<vector<__cxx11::basic_string<char> > >; _BinaryPredicate =
__gnu_cxx::__ops::_Iter_equal_to_iter]’ at
/usr/include/c++/12/bits/stl_algo.h:1002:17,
    inlined from ‘constexpr _OIter std::unique_copy(_IIter, _IIter, _OIter)
[with _IIter = __gnu_cxx::__normal_iterator<__cxx11::basic_string<char>*,
vector<__cxx11::basic_string<char> > >; _OIter =
insert_iterator<vector<__cxx11::basic_string<char> > >]’ at
/usr/include/c++/12/bits/stl_algo.h:4474:32,
    inlined from ‘int main()’ at unique_copy.cpp:18:21:
/usr/include/c++/12/bits/basic_string.h:204:43: warning: null pointer
dereference [-Wnull-dereference]
  204 |         : allocator_type(std::move(__a)), _M_p(__dat) { }
      |                                           ^~~~~~~~~~~
[...several more pages of similar output with more -Wnull-dereference
occurrences snipped...]


I could work around this bug by simply moving the call to std::sort() before
insert_iterator ctor (i.e. just exchanging the marked lines avoids the
warning), but it looks wrong to have to use such voodoo just to make my real
code compile without warnings again.

Reply via email to