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

            Bug ID: 125376
           Summary: Distinct C++26 placeholder variables (P2169) share
                    storage inside coroutine frames
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: nebkat at gmail dot com
  Target Milestone: ---

GCC   (trunk) -O3: https://godbolt.org/z/W19raTGjd
GCC   (trunk) -O0: https://godbolt.org/z/P6zrG91zW
GCC   (14.1 ) -O0: https://godbolt.org/z/8T93P4och
Clang (trunk) -O0: https://godbolt.org/z/Y1fGz8ajn (correct)

Per P2169, each `auto _` declaration introduces a distinct variable with its
own lifetime extending to end of scope. Only the name `_` becomes inaccessible
after a subsequent placeholder declaration in the same scope; the prior
variables remain alive and must continue to occupy distinct storage.

GCC honours this correctly for ordinary functions. Inside a coroutine body,
however, multiple `auto _` declarations are allocated to the same
coroutine-frame slot. The second declaration's constructor consequently writes
over the first variable's still-live storage. Any code that observes the first
variable after the second is declared sees corrupted bytes.

-Wuninitialized does fire on the buggy case (but not in -O0 or -Os):

  warning: '((A*)<unknown>)[7].A::value' is used uninitialized
[-Wuninitialized]
     17 |     ~A() { std::printf("  ~A() this=%p value=0x%08x\n", (void*)this,
value); }

This has been present since GCC14.1 when placeholder variables were introduced.

Reply via email to