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

Evgeniy Dushistov <dushistov at mail dot ru> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dushistov at mail dot ru

--- Comment #19 from Evgeniy Dushistov <dushistov at mail dot ru> ---
I saw problem similar `std::optional` may be unitialized case as desribed here
with boost::variant/boost::optional (c++11) and std::variant/std::optional
(c++17),
but in my case I have not only gcc warning, but valgrind also reports problem,
is it the same problem or gcc code generation bug?


```
//Foo.cpp
#include "Foo.hpp"

struct FooOpaque {};

FooOpaque *Foo_new() {
  auto p = new FooOpaque;
  return p;
}

void Foo_free(FooOpaque *p) { delete p; }

std::variant<std::optional<Foo>, std::string> f_res_opt(int var) {
  switch (var) {
  case 0:
    return {std::optional<Foo>{Foo{Foo_new()}}};
  case 1:
    return {std::optional<Foo>{}};
  case 2:
    return {std::string{}};
  default:
    std::abort();
  }
}

```

```
//Foo.hpp
#include <memory>
#include <optional>
#include <variant>

struct FooOpaque;
FooOpaque *Foo_new();
void Foo_free(FooOpaque *);

struct FooDeleter {
  void operator()(FooOpaque *p) { Foo_free(p); }
};

using Foo = std::unique_ptr<FooOpaque, FooDeleter>;

std::variant<std::optional<Foo>, std::string> f_res_opt(int var);
```

```
//main.cpp
#include "Foo.hpp"

int main() {

  auto res1 = f_res_opt(0);
  auto res1_ok = std::get<std::optional<Foo>>(std::move(res1));

  printf("step 2\n");

  auto res2 = f_res_opt(1);

  auto res2_ok = std::get<std::optional<Foo>>(std::move(res2));

  printf("step 3\n");

  auto res3 = f_res_opt(2);

  auto res3_ok = std::get<std::string>(std::move(res3));
}
```

gcc reports:
```
g++ -ggdb  -Ofast -Wall -Wextra -std=c++17 -pedantic  main.cpp Foo.cpp
In file included from main.cpp:1:
Foo.hpp: In function 'int main()':
Foo.hpp:10:43: warning: 'res2_ok.std::_Head_base<0, FooOpaque*,
false>::_M_head_impl' may be used uninitialized in this function
[-Wmaybe-uninitialized]
   10 |   void operator()(FooOpaque *p) { Foo_free(p); }
      |                                   ~~~~~~~~^~~
main.cpp:12:8: note: 'res2_ok.std::_Head_base<0, FooOpaque*,
false>::_M_head_impl' was declared here
   12 |   auto res2_ok = std::get<std::optional<Foo>>(std::move(res2));
      |        ^~~~~~~
In file included from main.cpp:1:
Foo.hpp:10:43: warning: 'res1_ok.std::_Head_base<0, FooOpaque*,
false>::_M_head_impl' may be used uninitialized in this function
[-Wmaybe-uninitialized]
   10 |   void operator()(FooOpaque *p) { Foo_free(p); }
      |                                   ~~~~~~~~^~~
main.cpp:6:8: note: 'res1_ok.std::_Head_base<0, FooOpaque*,
false>::_M_head_impl' was declared here
    6 |   auto res1_ok = std::get<std::optional<Foo>>(std::move(res1));
      |        ^~~~~~~
```

but valgrind also reports:

valgrind -v ./a.out

```
==7858== Conditional jump or move depends on uninitialised value(s)
==7858==    at 0x109374: ~unique_ptr (unique_ptr.h:288)
==7858==    by 0x109374: _M_destroy (optional:257)
==7858==    by 0x109374: _M_reset (optional:277)
==7858==    by 0x109374: ~_Optional_payload (optional:398)
==7858==    by 0x109374: ~_Optional_base (optional:471)
==7858==    by 0x109374: ~optional (optional:656)
==7858==    by 0x109374: main (main.cpp:12)
```

gcc 9.1.0 and valgrind 3.15.0.GIT

Reply via email to