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

Reply via email to