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

            Bug ID: 106664
           Summary: std::valarray::resize(0): spurious -Walloc-zero
                    warning
           Product: gcc
           Version: 12.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gchicares at sbcglobal dot net
  Target Milestone: ---

With -Walloc-zero and -O1 or greater, resizing a valarray to zero length
elicits a warning. Unexpected because the zero-byte allocation happens in a
system header, even though -Wsystem-headers is not specified.

Occurs with gcc-12 but not gcc-11, though gcc-11 would also allocate zero
bytes. Maybe _GLIBCXX_NOTHROW, added in gcc-12, explains that difference.

Copy ctor and operator=() are also affected. Looks like checking for zero in
__valarray_get_storage() would take care of those, too.

#include <valarray>
int main()
{
    std::valarray<double> w {1};
    w.resize(0); // warns

    // Similarly warns on other operations, e.g.:
    std::valarray<double> x;
    std::valarray<double> y {x}; // warns
}

$g++ -O1 -Walloc-zero va_resize_0.cpp    
In file included from /usr/include/c++/12/valarray:100,
                 from va_resize_0.cpp:1:
In function ‘_Tp* std::__valarray_get_storage(size_t) [with _Tp = double]’,
    inlined from ‘void std::valarray<_Tp>::resize(std::size_t, _Tp) [with _Tp =
double]’ at /usr/include/c++/12/valarray:1042:41,
    inlined from ‘int main()’ at va_resize_0.cpp:5:13:
/usr/include/c++/12/bits/valarray_array.h:58:44: warning: argument 1 value is
zero [-Walloc-zero]
   58 |     { return static_cast<_Tp*>(operator new(__n * sizeof(_Tp))); }
      |                                ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/12/bits/stl_construct.h:59,
                 from /usr/include/c++/12/bits/stl_tempbuf.h:60,
                 from /usr/include/c++/12/bits/stl_algo.h:61,
                 from /usr/include/c++/12/algorithm:61,
                 from /usr/include/c++/12/valarray:38:
/usr/include/c++/12/new: In function ‘int main()’:
/usr/include/c++/12/new:126:26: note: in a call to allocation function ‘void*
operator new(std::size_t)’ declared here
  126 | _GLIBCXX_NODISCARD void* operator new(std::size_t) _GLIBCXX_THROW
(std::bad_alloc)
      |                          ^~~~~~~~
In function ‘_Tp* std::__valarray_get_storage(size_t) [with _Tp = double]’,
    inlined from ‘std::valarray<_Tp>::valarray(const std::valarray<_Tp>&) [with
_Tp = double]’ at /usr/include/c++/12/valarray:647:64,
    inlined from ‘int main()’ at va_resize_0.cpp:9:31:
/usr/include/c++/12/bits/valarray_array.h:58:44: warning: argument 1 value is
zero [-Walloc-zero]
   58 |     { return static_cast<_Tp*>(operator new(__n * sizeof(_Tp))); }
      |                                ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
/usr/include/c++/12/new: In function ‘int main()’:
/usr/include/c++/12/new:126:26: note: in a call to allocation function ‘void*
operator new(std::size_t)’ declared here
  126 | _GLIBCXX_NODISCARD void* operator new(std::size_t) _GLIBCXX_THROW
(std::bad_alloc)
      |                          ^~~~~~~~

Reply via email to