Public bug reported:

Release: Ubuntu 26.04.1 LTS (resolute)
Package: g++-15 15.2.0-16ubuntu1

g++-15 emits a false-positive -Wmaybe-uninitialized warning when a structured
binding is initialized from a co_await expression in a coroutine. With
-Werror, this breaks the build of valid C++20 code, in particular the common
Boost.Asio idiom:

    auto [ec, result] = co_await
op(boost::asio::as_tuple(boost::asio::use_awaitable));

This is an upstream GCC 15 regression that is already fixed on the GCC 16
branch:
- GCC 14.3: no warning
- GCC 15.2: warning (also this package, 15.2.0-16ubuntu1)
- GCC 16.1: warning
- GCC 16.2: no warning (also Debian forky, g++ 16.2.0-3)
(-std=c++20 -O1 -Wall on all of them.)

The fix landed upstream on releases/gcc-16 between 16.1 and 16.2. Since 26.04
is an LTS release that keeps GCC 15 as its default compiler, could the fix be
backported to gcc-15 once it is identified upstream?

Upstream report: https://gcc.gnu.org/pipermail/gcc-help/2026-October/145199.html
(gcc-help thread; no GCC Bugzilla PR yet)

Steps to reproduce:

1. Save the following as repro.cpp:

#include <coroutine>
#include <memory>
#include <tuple>
#include <utility>

struct task {
    struct promise_type {
        std::shared_ptr<int> value;
        task get_return_object() { return {}; }
        std::suspend_always initial_suspend() noexcept { return {}; }
        std::suspend_always final_suspend() noexcept { return {}; }
        void return_value(std::shared_ptr<int> v) { value = std::move(v); }
        void unhandled_exception() noexcept {}
    };
};

extern std::coroutine_handle<> pending;

struct op {
    std::tuple<int, std::shared_ptr<int>> result;
    bool await_ready() const noexcept { return false; }
    void await_suspend(std::coroutine_handle<> h) noexcept { pending = h; }
    std::tuple<int, std::shared_ptr<int>> await_resume() { return 
std::move(result); }
};

op async_op();

task f()
{
    auto [ec, r] = co_await async_op();
    co_return r;
}

2. Run:

    g++-15 -std=c++20 -O1 -Wall -c repro.cpp

Expected result: no warning (the binding is always initialized).

Actual result:

    repro.cpp: In function 'void f(_Z1fv.Frame*)':
    repro.cpp:32:1: warning: '<anonymous>' may be used uninitialized 
[-Wmaybe-uninitialized]
       32 | }
          | ^
    repro.cpp:30:38: note: '<anonymous>' was declared here
       30 |     auto [ec, r] = co_await async_op();
          |                                      ^

Further observations on 15.2.0-16ubuntu1:
- warns at -O1, -O2, -O3 and -Os; no warning at -O0;
- same result with -std=c++20, -std=c++23 and -std=c++26;
- no warning when the tuple is a named variable instead of a structured
  binding:
      auto t = co_await async_op(); auto& r = std::get<1>(t);
- no warning for the same structured binding in a regular (non-coroutine)
  function.

Workaround: -Wno-maybe-uninitialized.

** Affects: gcc-15 (Ubuntu)
     Importance: Undecided
         Status: New

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2170751

Title:
  -Wmaybe-uninitialized false positive on structured binding initialized
  from co_await (fixed in GCC 16.2)

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/gcc-15/+bug/2170751/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to