title: Different logic produced by clang and gcc for same code. Which is correct?
body: <p>I have found a discrepancy between the logic produced by gcc-8 and clang-6. </p>
  
  <p>This happened in a real code base, when having developed using clang, I deployed using gcc.</p>
  
  <p>Please kindly advise which compiler is in error so that I can file a bug appropriately.</p>
  
  <h3>Synopsis</h3>
  
  <p><code>A</code> is implicitly convertible to <code>B</code>
  <code>A</code> is constructible from both an <code>A</code> (copy/move) and <code>std::initializer_list&lt;B&gt;</code>.</p>
  
  <p>When initialising an <code>A</code> from an <code>A&amp;&amp;</code>:</p>
  
  <ul>
  <li>clang selects the move-constructor</li>
  <li>gcc selects the <code>initializer_list</code> constructor.</li>
  </ul>
  
  <p>live demonstration: <a href="https://coliru.stacked-crooked.com/a/bc50bd8f040d6476" rel="nofollow noreferrer">https://coliru.stacked-crooked.com/a/bc50bd8f040d6476</a></p>
  
  <h3>MCVE</h3>
  
  <pre><code>#include &lt;initializer_list&gt;
  #include &lt;utility&gt;
  #include &lt;iostream&gt;
  
  struct thing;
  
  struct thing_ref
  {
      thing_ref(thing&amp;&amp; other) : ref_(other) {}
      thing_ref(thing&amp; other) : ref_(other) {}
  
      thing&amp; ref_;
  };
  
  struct thing
  {
      thing() {}
  
      thing(std::initializer_list&lt;thing_ref&gt; things)
      {
          std::cout &lt;&lt; "initializer_list path\n";
      }
  
      thing(thing&amp;&amp; other)
      {
          std::cout &lt;&lt; "move path\n";
      }
  
      thing(thing const&amp; other)
      {
          std::cout &lt;&lt; "copy path\n";
      }
  };
  
  struct foo
  {
      foo(thing t) : mything { std::move(t) } {}
      thing mything;
  };
  
  int main()
  {
      thing t;
  
      auto f = foo { std::move(t) };
  }
  </code></pre>
  
  <h3>Compiler settings:</h3>
  
  <p>Nothing special, as per the coliru link: <code>-std=c++17 -O2</code></p>