* More aggressive GCC 12 -Wmaybe-uninitialized when using <functional>
@ 2021-07-22 9:19 Stephan Bergmann
2021-07-22 10:03 ` Jonathan Wakely
0 siblings, 1 reply; 4+ messages in thread
From: Stephan Bergmann @ 2021-07-22 9:19 UTC (permalink / raw)
To: gcc, libstdc++
Compared to GCC 11 (at least gcc-c++-11.1.1-3.fc34.x86_64), recent GCC
12 trunk emits two "unhelpful" -Wmaybe-uninitialized for
> $ cat test.cc
> #include <functional>
> using fn = std::function<void()>;
> fn f(fn x) {
> fn a;
> a = x;
> return x;
> }
> $ ~/gcc/trunk/inst/bin/g++ -c -Wmaybe-uninitialized -O2 test.cc
> In file included from ~/gcc/trunk/inst/include/c++/12.0.0/bits/stl_function.h:60,
> from ~/gcc/trunk/inst/include/c++/12.0.0/functional:49,
> from test.cc:1:
> In function ‘std::_Require<std::__not_<std::__is_tuple_like<_Tp> >, std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with _Tp = void (*)(const std::_Any_data&)]’,
> inlined from ‘void std::function<_Res(_ArgTypes ...)>::swap(std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:529:11,
> inlined from ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:20,
> inlined from ‘fn f(fn)’ at test.cc:5:9:
> ~/gcc/trunk/inst/include/c++/12.0.0/bits/move.h:204:11: warning: ‘<unnamed>.std::function<void()>::_M_invoker’ may be used uninitialized [-Wmaybe-uninitialized]
> 204 | _Tp __tmp = _GLIBCXX_MOVE(__a);
> | ^~~~~
> In file included from ~/gcc/trunk/inst/include/c++/12.0.0/functional:59,
> from test.cc:1:
> ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h: In function ‘fn f(fn)’:
> ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:9: note: ‘<anonymous>’ declared here
> 442 | function(__x).swap(*this);
> | ^~~~~~~~~~~~~
> In file included from ~/gcc/trunk/inst/include/c++/12.0.0/bits/stl_function.h:60,
> from ~/gcc/trunk/inst/include/c++/12.0.0/functional:49,
> from test.cc:1:
> In function ‘std::_Require<std::__not_<std::__is_tuple_like<_Tp> >, std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with _Tp = std::_Any_data]’,
> inlined from ‘void std::function<_Res(_ArgTypes ...)>::swap(std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:527:11,
> inlined from ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:20,
> inlined from ‘fn f(fn)’ at test.cc:5:9:
> ~/gcc/trunk/inst/include/c++/12.0.0/bits/move.h:204:11: warning: ‘*(std::_Any_data*)((char*)&<unnamed> + offsetof(std::function, std::function<void()>::<unnamed>))’ may be used uninitialized [-Wmaybe-uninitialized]
> 204 | _Tp __tmp = _GLIBCXX_MOVE(__a);
> | ^~~~~
> In file included from ~/gcc/trunk/inst/include/c++/12.0.0/functional:59,
> from test.cc:1:
> ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h: In function ‘fn f(fn)’:
> ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:9: note: ‘<anonymous>’ declared here
> 442 | function(__x).swap(*this);
> | ^~~~~~~~~~~~~
This appears to be an issue with more aggressive -Wmaybe-uninitialized
in GCC 12 vs. 11, rather than an issue with changes to <functional> in
libstdc++ 12 vs. 11, as effectively the same warnings are emitted when I
use GCC 12 with libstdc++ 11 with
> $ ~/gcc/trunk/inst/bin/g++ -c -Wmaybe-uninitialized -O2 -nostdinc++ -isystem /usr/include/c++/11 -isystem /usr/include/c++/11/x86_64-redhat-linux test.cc
The warnings may technically be correct, and I'm not sure whether this
is something that should be addressed in the GCC code emitting the
warnings or in the libstdc++ <functional> implementation.
(I found this when building LibreOffice with recent GCC 12 trunk.)
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: More aggressive GCC 12 -Wmaybe-uninitialized when using <functional>
2021-07-22 9:19 More aggressive GCC 12 -Wmaybe-uninitialized when using <functional> Stephan Bergmann
@ 2021-07-22 10:03 ` Jonathan Wakely
2021-07-22 13:36 ` Jonathan Wakely
2021-07-23 9:58 ` Stephan Bergmann
0 siblings, 2 replies; 4+ messages in thread
From: Jonathan Wakely @ 2021-07-22 10:03 UTC (permalink / raw)
To: Stephan Bergmann; +Cc: gcc Mailing List, libstdc++
On Thu, 22 Jul 2021 at 10:23, Stephan Bergmann via Libstdc++
<libstdc++@gcc.gnu.org> wrote:
>
> Compared to GCC 11 (at least gcc-c++-11.1.1-3.fc34.x86_64), recent GCC
> 12 trunk emits two "unhelpful" -Wmaybe-uninitialized for
>
> > $ cat test.cc
> > #include <functional>
> > using fn = std::function<void()>;
> > fn f(fn x) {
> > fn a;
> > a = x;
> > return x;
> > }
>
> > $ ~/gcc/trunk/inst/bin/g++ -c -Wmaybe-uninitialized -O2 test.cc
> > In file included from ~/gcc/trunk/inst/include/c++/12.0.0/bits/stl_function.h:60,
> > from ~/gcc/trunk/inst/include/c++/12.0.0/functional:49,
> > from test.cc:1:
> > In function ‘std::_Require<std::__not_<std::__is_tuple_like<_Tp> >, std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with _Tp = void (*)(const std::_Any_data&)]’,
> > inlined from ‘void std::function<_Res(_ArgTypes ...)>::swap(std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:529:11,
> > inlined from ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:20,
> > inlined from ‘fn f(fn)’ at test.cc:5:9:
> > ~/gcc/trunk/inst/include/c++/12.0.0/bits/move.h:204:11: warning: ‘<unnamed>.std::function<void()>::_M_invoker’ may be used uninitialized [-Wmaybe-uninitialized]
> > 204 | _Tp __tmp = _GLIBCXX_MOVE(__a);
> > | ^~~~~
> > In file included from ~/gcc/trunk/inst/include/c++/12.0.0/functional:59,
> > from test.cc:1:
> > ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h: In function ‘fn f(fn)’:
> > ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:9: note: ‘<anonymous>’ declared here
> > 442 | function(__x).swap(*this);
> > | ^~~~~~~~~~~~~
> > In file included from ~/gcc/trunk/inst/include/c++/12.0.0/bits/stl_function.h:60,
> > from ~/gcc/trunk/inst/include/c++/12.0.0/functional:49,
> > from test.cc:1:
> > In function ‘std::_Require<std::__not_<std::__is_tuple_like<_Tp> >, std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with _Tp = std::_Any_data]’,
> > inlined from ‘void std::function<_Res(_ArgTypes ...)>::swap(std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:527:11,
> > inlined from ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:20,
> > inlined from ‘fn f(fn)’ at test.cc:5:9:
> > ~/gcc/trunk/inst/include/c++/12.0.0/bits/move.h:204:11: warning: ‘*(std::_Any_data*)((char*)&<unnamed> + offsetof(std::function, std::function<void()>::<unnamed>))’ may be used uninitialized [-Wmaybe-uninitialized]
> > 204 | _Tp __tmp = _GLIBCXX_MOVE(__a);
> > | ^~~~~
> > In file included from ~/gcc/trunk/inst/include/c++/12.0.0/functional:59,
> > from test.cc:1:
> > ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h: In function ‘fn f(fn)’:
> > ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:9: note: ‘<anonymous>’ declared here
> > 442 | function(__x).swap(*this);
> > | ^~~~~~~~~~~~~
>
> This appears to be an issue with more aggressive -Wmaybe-uninitialized
> in GCC 12 vs. 11, rather than an issue with changes to <functional> in
> libstdc++ 12 vs. 11, as effectively the same warnings are emitted when I
> use GCC 12 with libstdc++ 11 with
>
> > $ ~/gcc/trunk/inst/bin/g++ -c -Wmaybe-uninitialized -O2 -nostdinc++ -isystem /usr/include/c++/11 -isystem /usr/include/c++/11/x86_64-redhat-linux test.cc
>
> The warnings may technically be correct, and I'm not sure whether this
> is something that should be addressed in the GCC code emitting the
> warnings or in the libstdc++ <functional> implementation.
>
> (I found this when building LibreOffice with recent GCC 12 trunk.)
The problem is that the _Function_base default constructor is
user-provided, so when std::function value-initializes its base class,
that doesn't do zero-init first. It just calls the default ctor, which
doesn't initialize the _M_fucntor member.
This should fix it:
--- a/libstdc++-v3/include/bits/std_function.h
+++ b/libstdc++-v3/include/bits/std_function.h
@@ -237,7 +237,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ __functor._M_access<_Functor*>() = new _Functor(std::move(__f)); }
};
- _Function_base() : _M_manager(nullptr) { }
+ _Function_base() = default;
~_Function_base()
{
@@ -250,8 +250,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef bool (*_Manager_type)(_Any_data&, const _Any_data&,
_Manager_operation);
- _Any_data _M_functor;
- _Manager_type _M_manager;
+ _Any_data _M_functor{};
+ _Manager_type _M_manager{};
};
template<typename _Signature, typename _Functor>
@@ -634,8 +634,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private:
using _Invoker_type = _Res (*)(const _Any_data&, _ArgTypes&&...);
- _Invoker_type _M_invoker;
- };
+ _Invoker_type _M_invoker = nullptr;
+ };
#if __cpp_deduction_guides >= 201606
template<typename>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: More aggressive GCC 12 -Wmaybe-uninitialized when using <functional>
2021-07-22 10:03 ` Jonathan Wakely
@ 2021-07-22 13:36 ` Jonathan Wakely
2021-07-23 9:58 ` Stephan Bergmann
1 sibling, 0 replies; 4+ messages in thread
From: Jonathan Wakely @ 2021-07-22 13:36 UTC (permalink / raw)
To: Stephan Bergmann; +Cc: gcc Mailing List, libstdc++, gcc Patches
[-- Attachment #1: Type: text/plain, Size: 4888 bytes --]
On Thu, 22 Jul 2021 at 11:03, Jonathan Wakely wrote:
>
> On Thu, 22 Jul 2021 at 10:23, Stephan Bergmann via Libstdc++
> <libstdc++@gcc.gnu.org> wrote:
> >
> > Compared to GCC 11 (at least gcc-c++-11.1.1-3.fc34.x86_64), recent GCC
> > 12 trunk emits two "unhelpful" -Wmaybe-uninitialized for
> >
> > > $ cat test.cc
> > > #include <functional>
> > > using fn = std::function<void()>;
> > > fn f(fn x) {
> > > fn a;
> > > a = x;
> > > return x;
> > > }
> >
> > > $ ~/gcc/trunk/inst/bin/g++ -c -Wmaybe-uninitialized -O2 test.cc
> > > In file included from ~/gcc/trunk/inst/include/c++/12.0.0/bits/stl_function.h:60,
> > > from ~/gcc/trunk/inst/include/c++/12.0.0/functional:49,
> > > from test.cc:1:
> > > In function ‘std::_Require<std::__not_<std::__is_tuple_like<_Tp> >, std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with _Tp = void (*)(const std::_Any_data&)]’,
> > > inlined from ‘void std::function<_Res(_ArgTypes ...)>::swap(std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:529:11,
> > > inlined from ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:20,
> > > inlined from ‘fn f(fn)’ at test.cc:5:9:
> > > ~/gcc/trunk/inst/include/c++/12.0.0/bits/move.h:204:11: warning: ‘<unnamed>.std::function<void()>::_M_invoker’ may be used uninitialized [-Wmaybe-uninitialized]
> > > 204 | _Tp __tmp = _GLIBCXX_MOVE(__a);
> > > | ^~~~~
> > > In file included from ~/gcc/trunk/inst/include/c++/12.0.0/functional:59,
> > > from test.cc:1:
> > > ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h: In function ‘fn f(fn)’:
> > > ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:9: note: ‘<anonymous>’ declared here
> > > 442 | function(__x).swap(*this);
> > > | ^~~~~~~~~~~~~
> > > In file included from ~/gcc/trunk/inst/include/c++/12.0.0/bits/stl_function.h:60,
> > > from ~/gcc/trunk/inst/include/c++/12.0.0/functional:49,
> > > from test.cc:1:
> > > In function ‘std::_Require<std::__not_<std::__is_tuple_like<_Tp> >, std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with _Tp = std::_Any_data]’,
> > > inlined from ‘void std::function<_Res(_ArgTypes ...)>::swap(std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:527:11,
> > > inlined from ‘std::function<_Res(_ArgTypes ...)>& std::function<_Res(_ArgTypes ...)>::operator=(const std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]’ at ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:20,
> > > inlined from ‘fn f(fn)’ at test.cc:5:9:
> > > ~/gcc/trunk/inst/include/c++/12.0.0/bits/move.h:204:11: warning: ‘*(std::_Any_data*)((char*)&<unnamed> + offsetof(std::function, std::function<void()>::<unnamed>))’ may be used uninitialized [-Wmaybe-uninitialized]
> > > 204 | _Tp __tmp = _GLIBCXX_MOVE(__a);
> > > | ^~~~~
> > > In file included from ~/gcc/trunk/inst/include/c++/12.0.0/functional:59,
> > > from test.cc:1:
> > > ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h: In function ‘fn f(fn)’:
> > > ~/gcc/trunk/inst/include/c++/12.0.0/bits/std_function.h:442:9: note: ‘<anonymous>’ declared here
> > > 442 | function(__x).swap(*this);
> > > | ^~~~~~~~~~~~~
> >
> > This appears to be an issue with more aggressive -Wmaybe-uninitialized
> > in GCC 12 vs. 11, rather than an issue with changes to <functional> in
> > libstdc++ 12 vs. 11, as effectively the same warnings are emitted when I
> > use GCC 12 with libstdc++ 11 with
> >
> > > $ ~/gcc/trunk/inst/bin/g++ -c -Wmaybe-uninitialized -O2 -nostdinc++ -isystem /usr/include/c++/11 -isystem /usr/include/c++/11/x86_64-redhat-linux test.cc
> >
> > The warnings may technically be correct, and I'm not sure whether this
> > is something that should be addressed in the GCC code emitting the
> > warnings or in the libstdc++ <functional> implementation.
> >
> > (I found this when building LibreOffice with recent GCC 12 trunk.)
>
> The problem is that the _Function_base default constructor is
> user-provided, so when std::function value-initializes its base class,
> that doesn't do zero-init first. It just calls the default ctor, which
> doesn't initialize the _M_fucntor member.
I've pushed the attached patch to trunk, after testing on powerpc64le-linux.
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 2763 bytes --]
commit c22bcfd2f7dc9bb5ad394720f4a612327dc898ba
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Thu Jul 22 11:57:38 2021
libstdc++: Initialize all subobjects of std::function
The std::function::swap member swaps each data member unconditionally,
resulting in -Wmaybe-uninitialized warnings for a default constructed
object. This happens because the _M_invoker and _M_functor members are
only initialized if the function has a target.
This change ensures that all subobjects are zero-initialized on
construction.
Signed-off-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
* include/bits/std_function.h (_Function_base): Add
default member initializers and define constructor as defaulted.
(function::_M_invoker): Add default member initializer.
diff --git a/libstdc++-v3/include/bits/std_function.h b/libstdc++-v3/include/bits/std_function.h
index 31eba2b822c..c08484465c9 100644
--- a/libstdc++-v3/include/bits/std_function.h
+++ b/libstdc++-v3/include/bits/std_function.h
@@ -237,7 +237,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ __functor._M_access<_Functor*>() = new _Functor(std::move(__f)); }
};
- _Function_base() : _M_manager(nullptr) { }
+ _Function_base() = default;
~_Function_base()
{
@@ -247,11 +247,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool _M_empty() const { return !_M_manager; }
- typedef bool (*_Manager_type)(_Any_data&, const _Any_data&,
- _Manager_operation);
+ using _Manager_type
+ = bool (*)(_Any_data&, const _Any_data&, _Manager_operation);
- _Any_data _M_functor;
- _Manager_type _M_manager;
+ _Any_data _M_functor{};
+ _Manager_type _M_manager{};
};
template<typename _Signature, typename _Functor>
@@ -261,7 +261,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
class _Function_handler<_Res(_ArgTypes...), _Functor>
: public _Function_base::_Base_manager<_Functor>
{
- typedef _Function_base::_Base_manager<_Functor> _Base;
+ using _Base = _Function_base::_Base_manager<_Functor>;
public:
static bool
@@ -414,7 +414,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
function(_Functor __f)
: _Function_base()
{
- typedef _Function_handler<_Res(_ArgTypes...), _Functor> _My_handler;
+ using _My_handler = _Function_handler<_Res(_ArgTypes...), _Functor>;
if (_My_handler::_M_not_empty_function(__f))
{
@@ -634,8 +634,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private:
using _Invoker_type = _Res (*)(const _Any_data&, _ArgTypes&&...);
- _Invoker_type _M_invoker;
- };
+ _Invoker_type _M_invoker = nullptr;
+ };
#if __cpp_deduction_guides >= 201606
template<typename>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: More aggressive GCC 12 -Wmaybe-uninitialized when using <functional>
2021-07-22 10:03 ` Jonathan Wakely
2021-07-22 13:36 ` Jonathan Wakely
@ 2021-07-23 9:58 ` Stephan Bergmann
1 sibling, 0 replies; 4+ messages in thread
From: Stephan Bergmann @ 2021-07-23 9:58 UTC (permalink / raw)
To: Jonathan Wakely; +Cc: gcc Mailing List, libstdc++
On 22/07/2021 12:03, Jonathan Wakely wrote:
> This should fix it:
[...]
Thanks; it indeed fixed the LibreOffice build for me.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-07-23 9:58 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-22 9:19 More aggressive GCC 12 -Wmaybe-uninitialized when using <functional> Stephan Bergmann
2021-07-22 10:03 ` Jonathan Wakely
2021-07-22 13:36 ` Jonathan Wakely
2021-07-23 9:58 ` Stephan Bergmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).