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

            Bug ID: 118386
           Summary: Optimizations loose rvalue references from
                    std::tuple<T&&> and std::tuple<const T&>
           Product: gcc
           Version: 11.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: valiente.arthur at gmail dot com
  Target Milestone: ---

Compiler explorer playground available here: 
https://godbolt.org/z/fGedfnrco

---

Hello everyone,

First of all, I hope the code described here are valid cpp code and don't fall
into my misunderstanding of cpp and undefined behavior territory. I'm sorry if
it's the case.

It appears that any `T&&` or `const T&` initialized with a rvalue inside a
tuple gets optimized away by any optimization level from -O1 to -O3.

Here is a simple example showcasing the bug: 

```cpp
#include <tuple>

int main() {
    auto tpl = std::tuple<int&&>(42);

    // Also fails:
    // auto tpl = std::tuple<const int&>(42);


    // But this works:
    // int var = 42;
    // auto tpl = std::tuple<const int&>(var);
    //
    // OR even:
    // return std::get<0>(std::tuple<int&&>(42));


    // This fails (i.e. does not return 42)
    return std::get<0>(tpl);
}
```

Compiling with either clang (any level of optimization) or gcc -O0 works fine
(returns 42).

When compiling with gcc and any of -O1, -O2 or -O3, the code above does not
return the expected 42. 
Yet, `-Wuninitialized` outputs a warning concerning an unused <anonymous>
variable inside the tuple.

Additionally, I don't know if it's linked to this or not, but the following
snippet below produces the same king of issues (variables initialized by a
rvalue gets removed by optimization):

```cpp
for(auto&& [foo, bar] : {
  std::forward_as_tuple("foo", 42), 
  std::forward_as_tuple("bar", 24), 
  ...
}) {
  ...
} 
```

Yet it works fine when compiling in -std=c++23 and above, which is not the case
of the first snippet using the return value above.

A full example is available in compiler explorer: 
https://godbolt.org/z/fGedfnrco

An old bug report (2014) seems to refer to the same kind of bug
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61213) yet using
`-fno-indirect-inlining` didn't change anything.

Reply via email to