<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">