<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/105932>105932</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [Clang] [C++20] Trivial copy of variant member array where some subobjects have been destroyed is rejected in a constant expression
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          MitalAshok
      </td>
    </tr>
</table>

<pre>
    Since C++20 [P1331R2](https://wg21.link/P1331R2), a constructor call doesn't need to leave all of an object initialized.

Take this <https://godbolt.org/z/63vo7MP9o>:

```c++
#include <memory>

union U {
  int arr[4];
};

struct S1 {
 union {
    int arr[4];
  };
  S1() = default;
  constexpr S1(const S1& other) {
    arr[0] = other.arr[0];
    std::destroy(arr + 1, arr + 4);
  }
};

struct S2 {
  union {
    int arr[4];
  };
};

template<typename T>
consteval bool f() {
 T u1;
    u1.arr[0] = 123;
    std::destroy(u1.arr + 1, u1.arr + 4);
    // assert(std::is_within_lifetime(&u1.arr) && std::is_within_lifetime(u1.arr + 0) && !std::is_within_lifetime(u1.arr + 1));
    T u2 = u1;
    return u2.arr[0] == 123;
}

static_assert(f<U>());
static_assert(f<S1>());
static_assert(f<S2>());
```

Clang errors on `f<S2>()`:

```c++
<source>:36:15: error: static assertion expression is not an integral constant expression
   36 | static_assert(f<S2>());
      |               ^~~~~~~
<source>:30:12: note: subobject 'arr' is not initialized
   30 |     T u2 = u1;
      | ^
<source>:30:12: note: in call to 'S2(u1)'
   30 |     T u2 = u1;
      |            ^~
<source>:36:15: note: in call to 'f<S2>()'
   36 | static_assert(f<S2>());
      | ^~~~~~~
<source>:20:9: note: subobject declared here
   20 |     int arr[4];
      |         ^
```

It should not be a problem that the entirety of `'arr'` isn't initialized (it was fine with the non-trivial copy constructor of `S1` and with the union `U`)

GCC accepts this. MSVC does not accept `f<U>()` or `f<S2>()`.

</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysVsGO4jgQ_RpzKQ1KKgkhBw5AD6s9jDRauvc6cpIK8Y6xke3Qyxz221d2AgSGme5ZLWrRNnE9P78qvxS3VuwU0YJlK5Y9TXjnWm0Wn4Tjcmlb_XVS6vq02ApVEawZrhiuMAKWrT7HSRL_gSx7YjhvnTtYliwZbhhuXncYT6VQXxluzsuwYLgGDpVW1pmuctpAxaWEWpNVDHMHiqgGp0ESPxL4Z7oBrkCXf1HlQCjhBJfiG9VTFj2xaNl_P_OvBK4VFliyviWy03WppZtqs2O4-cZwM0uOOv_0udAs-eiXjXDYLOr_qv6Yw6-YCFXJriYPv6e9NicfOwrslNAKXoDlQwyAUA64MSxbpV6g5AyWj8bhu9cCtvEouscbof0QD2CMCLCNGc4ZFsCSJ6ip4Z10o8dBe_r7YPqFYRqGM9CuJRMix9v2W0YsewqIYdH0-uMIGsC62guaLGuyzugTwzk3BhiuIA6pHyapL4XbA7yhDY5J_Vdxvod3tD9I7ogla3c6kOJ7gudLanutjlxCqbWE5izsZeNn6OIbAbp4eqdXjMlbEvVBV5VG8zuhAPqaBm4tGcdwfoET9surcK1QX6RoyIk9BbazgZGnjTOf5Z9HjPaORkEM43fHxeGe39J-hg6DHHd6GXKdUdDhnWz3yl0rZKgK7kT15aJCw5L1i09bSNB480crt_H7l-LDpRebGJNaS652QMZoY8HX5yy6h5hF7_ObZG11ZyrqDSqZsWQZZyxZ9uh-0JMd6sDfBn-lyVo_FBaUdt41hXK0M1z2t54rN1p2SUIyA5av4ReOD-Hjg24_LPv4T_g8PoY_fIyevdL-yi3BduVg7AzzUKb5mf3I6a9Mo8umPyqonhbLPr6XglD9K8hpz2GLoZbDefNf3_dOi7ey-ZjDd8Ln_0uqfp4c9MoUj3NTUyW5oRpaMnSBxasoPzTfe12ueXl0gX53YFvdyToUQEnA4WB0KWkPruUOXEtAyglD7uTbAh9-Lhs2i0AMPcSodIDhXDh45RYaoQi8cQUcpdUHZ8RRhMtxON30JD32NvagXNXXqOHFM4tewt7FmP1v6zXwqqKDs6ETmcKn7Z_r0Nr01zE8O7vCy9gUQJvHbjH0OJN6kdRFUvAJLeIc07TA-TydtAssEt5Q3qRUVU2Z16mfVJhlRZTyFKuJWGCEaTTHNCrSeZROm7ygMudNnsUZ5UnD0oj2XMiplMe975EmwtqOFnGUFQlOJC9J2tAYIlbe4Bj6dm9iFj7gQ9ntLEsjKayzVwgnnAzdZLDEYOnZ6tI4-vnzWHrdwJEb4e1pT_uSjC8mfoJXX29g9Z6uxWih9Y1hSaRgeINS7T3DkH_sx-rcYd763aQzcnHXGgrXduW00nuGG89--PfhYLRHY7gJaliGm0GQ4wL_DQAA__-2Xhiz">