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

            Bug ID: 126472
           Summary: Wrong initialization (zero-initialization) in
                    initializer_list
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mirko.yuenyong at teamviewer dot com
  Target Milestone: ---

Created attachment 65159
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65159&action=edit
Preprocessed cpp file

This code fails in initializing the initializer_list when
compiling with C++-20 whilst working correctly with C++-17.

The initializer_list seem to need at least 2 elements. Also the
elements need to have the quite complex type i.e.
tuple<optional<vector>, ...>. The additional types (the ...)
are relevant as they all seem to be uninitialized in case the
error occurs. In the code example we choose an int.

In the initializer_list's tuples one of the elements need to
have the optional as a nullopt and another one must contain a
non-empty vector. The order does not matter.

All tuple elements after the nullopt will be zero-initialized.

To reproduce the error call this:

/usr/lib/gcc-snapshot/bin/g++ -ggdb -freport-bug -save-temps -Wall -Wextra
-fno-strict-aliasing -fwrapv -std=c++20 init_failure.cpp -o init_failure.elf

This will incorrectly output the value "0" for the integer
tuple-element:

$ ./init_failure.elf
optional=<value>
int=42
optional=<none>
int=0

When using C++-17 instead the error does not appear and the
value "42" is printed for the integers.

This seems to be broken in recent snapshot version as well as
in GCC 16, 15, 14, 13 and 11 (i do not have 12).

Preprocessed file is attached, source code to reproduce is:

```
#include <iostream>
#include <optional>
#include <tuple>
#include <vector>

using InitList =
std::initializer_list<std::tuple<std::optional<std::vector<int>>, int>>;

const InitList data {
        std::tuple<std::optional<std::vector<int>>, int>(
                std::optional<std::vector<int>>(std::vector<int>(1, 42)),
                42),

        std::tuple<std::optional<std::vector<int>>, int>(
                std::optional<std::vector<int>>(),
                42),
};

int main()
{
        for (const auto& i : data) {
                std::cout << "optional=" << (std::get<0>(i).has_value() ?
"<value>" : "<none>") << "\n";
                std::cout << "int=" << std::get<1>(i) << "\n";
        }
}
```

Reply via email to