title: boost::optional strange uninitialize issue
body: <p>Time to time gcc gives warning about work with boost::optional via maybe-uninitialized , but I have supposed that this is false positive (like described here <a href="https://github.com/boostorg/optional/issues/72" rel="nofollow noreferrer">https://github.com/boostorg/optional/issues/72</a>).</p>
  
  <p>But now valgrind reports the same issue during runtime,
  so something wrong, any idea what is the problem:</p>
  
  <pre><code>//Foo.hpp
  #include &lt;boost/optional.hpp&gt;
  #include &lt;boost/variant.hpp&gt;
  #include &lt;cstdio&gt;
  #include &lt;string&gt;
  
  extern "C" {
  typedef struct FooOpaque FooOpaque;
  
  FooOpaque *Foo_new();
  
  void Foo_delete(const FooOpaque *self);
  }
  
  class Foo {
  public:
    explicit Foo(FooOpaque *o) noexcept : self_(o) {}
    Foo(const Foo &amp;) = delete;
    Foo &amp;operator=(const Foo &amp;) = delete;
  
    Foo(Foo &amp;&amp;o) noexcept : self_(o.self_) { o.self_ = nullptr; }
    Foo &amp;operator=(Foo &amp;&amp;o) noexcept {
  
      assert(this != &amp;o);
      free_mem(this-&gt;self_);
      self_ = o.self_;
      o.self_ = nullptr;
      return *this;
    }
    ~Foo() noexcept { free_mem(this-&gt;self_); }
  
  private:
    static void free_mem(FooOpaque *&amp;p) noexcept {
      //    printf("test\n");
      if (p != nullptr) {
        Foo_delete(p);
      }
      p = nullptr;
    }
  
    FooOpaque *self_ = nullptr;
  };
  
  boost::variant&lt;boost::optional&lt;Foo&gt;, std::string&gt; f_res_opt(int var);
  </code></pre>
  
  <pre><code>//Foo.cpp
  #include &lt;cassert&gt;
  #include &lt;cstdint&gt;
  #include &lt;cstring&gt;
  
  #include "Foo.hpp"
  
  extern "C" {
  struct FooOpaque {
    int data;
  };
  
  FooOpaque *Foo_new() {
    printf("Foo_new begin\n");
    auto p = new FooOpaque;
    p-&gt;data = 17;
    return p;
  }
  
  void Foo_delete(const FooOpaque *self) {
    assert(self != nullptr);
    printf("Foo_new delete\n");
    delete self;
  }
  }
  
  boost::variant&lt;boost::optional&lt;Foo&gt;, std::string&gt; f_res_opt(int var) {
    switch (var) {
    case 0:
      return {boost::optional&lt;Foo&gt;{Foo{Foo_new()}}};
    case 1:
      return {boost::optional&lt;Foo&gt;{boost::none}};
    case 2:
      return {std::string{}};
    default:
      std::abort();
    }
  }
  </code></pre>
  
  <pre><code>// main.cpp
  #include "Foo.hpp"
  
  int main() {
  
    auto res1 = f_res_opt(0);
    auto res1_ok = boost::get&lt;boost::optional&lt;Foo&gt;&gt;(boost::move(res1));
  
    printf("step 2\n");
  
    auto res2 = f_res_opt(1);
  
    auto res2_ok = boost::get&lt;boost::optional&lt;Foo&gt;&gt;(boost::move(res2));
  
    printf("step 3\n");
  
    auto res3 = f_res_opt(2);
  
    auto res3_ok = boost::get&lt;std::string&gt;(boost::move(res3));
  }
  </code></pre>
  
  <p>valgrind and gcc reports problem  in line:</p>
  
  <pre><code>auto res2_ok = boost::get&lt;boost::optional&lt;Foo&gt;&gt;(boost::move(res2));
  </code></pre>
  
  <p>that potentialy <code>Foo::free_mem</code> may be used for unitialized memory.</p>
  
  <p>The strange thing that if I enable printf in <code>Foo::free_mem</code>
  gcc warning (9.1.0) disappear and 
  valgrind (3.15) doesn't report any problems,
  if I comment it back gcc and valgrind reports the problem.</p>
  
  <p>I compile example with gcc in such way:</p>
  
  <pre class="lang-sh prettyprint-override"><code>g++ -ggdb -O3 -Wall -std=c++11 -Wextra main.cpp foo.cpp
  </code></pre>
  
  <p>So what is going on, error in my code, in boost::optional,
  or simultaneous error in valgrind and g++?</p>
  
  <p>May be this bug in g++ that generates wrong code and so valgrind also complain about error?</p>