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

            Bug ID: 92722
           Summary: gcc considers "padding" byte of empty lambda to be
                    uninitialized
           Product: gcc
           Version: 9.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rafael at espindo dot la
  Target Milestone: ---

Created attachment 47394
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47394&action=edit
testcase

seastar has a variant of std::function that cannot be copied and is called
noncopyable_function. It also has a small buffer so that small functions don't
need an indirection.

The implementation is careful to only move sizeof(Func) bytes to avoid using
uninitialized memory. It looks like gcc is careful enough to consider padding
bytes to be initialized, but when given an empty lambda, sizeof(Func) is 1 but
no bytes are actually used and gcc ends up issuing a warning.

A reduced testcase is attached. Compiling with g++ -S failure_injector_test.ii
-O1 -Wall produces the warning:

failure_injector_test.ii:22:27: warning: ‘a.noncopyable_function::direct[0]’ is
used uninitialized in this function [-Wuninitialized]

This seems to be generated because

    noncopyable_function(Func&& func) {
        static_assert(sizeof(Func) == 1);
        new (reinterpret_cast<Func*>(direct)) Func(std::move(func));
    }

Doesn't initialize any bytes, but sizeof(Func) is 1, so trivial_direct_move
still uses direrct[0]

Reply via email to