title: std::variant modification in constexpr
body: <p>Consider the following two programs:</p>
  
  <pre><code>#include&lt;variant&gt;
  #include&lt;iostream&gt;
  
  constexpr auto f() {
      using T = std::variant&lt;bool, int&gt;;
      T t(false);
      t = T(true);
      return std::get&lt;bool&gt;(t);
  }
  
  template&lt;auto V&gt; 
  void print() { std::cout &lt;&lt; V &lt;&lt; "\n"; }
  
  int main() {
      print&lt;f()&gt;();
  }
  </code></pre>
  
  <p>and</p>
  
  <pre><code>#include&lt;variant&gt;
  #include&lt;iostream&gt;
  
  constexpr auto f() {
      using T = std::variant&lt;bool, int&gt;;
      T t(false);
      t = T(42);
      return std::get&lt;int&gt;(t);
  }
  
  template&lt;auto V&gt; 
  void print() { std::cout &lt;&lt; V &lt;&lt; "\n"; }
  
  int main() {
      print&lt;f()&gt;();
  }
  </code></pre>
  
  <p>GCC compiles both of these and outputs the expected results. Clang does not compile any of them with the following error message in both cases:</p>
  
  <pre><code>&lt;source&gt;:4:16: error: constexpr function never produces a constant expression [-Winvalid-constexpr]
  constexpr auto f() {
                 ^
  &lt;source&gt;:7:7: note: non-constexpr function 'operator=' cannot be used in a constant expression
      t = T(42);
        ^
  /opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/variant:1095:16: note: declared here
        variant&amp; operator=(variant&amp;&amp;) = default;
  </code></pre>
  
  <p>Are the two programs well-formed? If not, why?</p>
  
  <p>Also if they are not well-formed, is the error message Clang gives appropriate? According to <a href="http://eel.is/c++draft/variant.assign" rel="noreferrer">[variant.assign]</a> the move assignment operator should be <code>constexpr</code>.</p>
  
  <p>Furthermore according to <a href="http://eel.is/c++draft/variant.variant#variant.assign-7.4" rel="noreferrer">(7.4)</a> the assignment in the second example should behave equivalent to <code>emplace&lt;int&gt;(...)</code> which is not declared <code>constexpr</code> (<a href="http://eel.is/c++draft/variant.variant#variant.mod" rel="noreferrer">[variant.mod]</a>). Does this imply the second example is ill-formed because the template argument cannot be evaluated as constant expression or does the wording allow/require this behavior?</p>
  
  <p>EDIT:</p>
  
  <p>Based on the comments it seems that Clang compiles and ouputs the correct results if libc++ is used and the error occurs only with libstdc++. Is this an incompatibility between the standard library and compiler?</p>
  
  <p>On <a href="https://godbolt.org/" rel="noreferrer">https://godbolt.org/</a>:</p>
  
  <p>Works in both cases:</p>
  
  <ul>
  <li>GCC 8.2.0 "-std=c++17"</li>
  <li>Clang 7.0.0 "-std=c++17 -stdlib=libc++"</li>
  </ul>
  
  <p>Does not work in either case:</p>
  
  <ul>
  <li>Clang 7.0.0 "-std=c++17"</li>
  </ul>