https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122029
Bug ID: 122029
Summary: False positive -Werror=maybe-uninitialized with two
member std::function objects
Product: gcc
Version: 12.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: sandberg.sven at gmail dot com
Target Milestone: ---
The following code gives a false (AFAICT) "-Werror=maybe-uninitialized"
warning. See also https://godbolt.org/z/qafdvvxox
```
#include <functional>
using Func_t = std::function<void()>;
struct C {
C() = default;
C(Func_t func) : m_func2(func) {}
Func_t m_func1;
Func_t m_func2;
};
void f() {
Func_t func([]{});
C c1(func);
C c2;
c2 = c1;
}
```
Verified in gcc 12.1 up to trunk (at the time of this writing, Godbolt's
highest-numbered version is 15.2)
The error message is:
```
In file included from
/cefs/73/73574545c1246435e304eea2_consolidated/compilers_c++_x86_gcc_12.1.0/include/c++/12.1.0/functional:59,
from <source>:1:
In copy constructor 'std::function<_Res(_ArgTypes ...)>::function(const
std::function<_Res(_ArgTypes ...)>&) [with _Res = void; _ArgTypes = {}]',
inlined from 'C::C(Func_t)' at <source>:7:22,
inlined from 'void f()' at <source>:14:14:
/cefs/73/73574545c1246435e304eea2_consolidated/compilers_c++_x86_gcc_12.1.0/include/c++/12.1.0/bits/std_function.h:391:17:
error: '<anonymous>' may be used uninitialized [-Werror=maybe-uninitialized]
391 | __x._M_manager(_M_functor, __x._M_functor,
__clone_functor);
| ~~~~^~~~~~~~~~
/cefs/73/73574545c1246435e304eea2_consolidated/compilers_c++_x86_gcc_12.1.0/include/c++/12.1.0/bits/std_function.h:
In function 'void f()':
/cefs/73/73574545c1246435e304eea2_consolidated/compilers_c++_x86_gcc_12.1.0/include/c++/12.1.0/bits/std_function.h:267:7:
note: by argument 2 of type 'const std::_Any_data&' to 'static bool
std::_Function_handler<_Res(_ArgTypes ...),
_Functor>::_M_manager(std::_Any_data&, const std::_Any_data&,
std::_Manager_operation) [with _Res = void; _Functor = f()::<lambda()>;
_ArgTypes = {}]' declared here
267 | _M_manager(_Any_data& __dest, const _Any_data& __source,
| ^~~~~~~~~~
<source>:14:14: note: '<anonymous>' declared here
14 | C c1(func);
| ^
```
The error goes away if we change the scenario in any one of the following ways:
- use gcc 11.4
- remove the `m_func1` member
- change order between the members `m_func1` and `m_func2`
- do not initialize `m_func2` in the constructor
- initialize `m_func1` inline, like `Func_t m_func1{[]{}}`
- use gcc-trunk and initialize c2 using copy constructor instead of copy
assignment operator, like `C c2 = c1` (but the error remains on gcc 12.1)
- initialize `c2` using move assignment operator instead of copy assignment
operator
- change the constructor to take func by reference or const reference
- change the constructor to take func by rvalue reference and use
`c2 = std::move(c1)`
- change the constructor argument to a template type (so that `f` does not need
to wrap it in `std::function`)
- use gcc 12.1 and replace `void f` by `int main` (but the error remains on
gcc-trunk)
- compile on mips64
The error does not go away if we change the scenario in any the following ways:
- Invoke the constructor with a temporary, like `C c1{[]{}}`
- initialize `m_func1` inline using `Func_t m_func1{}`
- compile on arm