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

    <tr>
        <th>Summary</th>
        <td>
            [clang] fails to compile valid code involving `variant` and `unordered_map` with libstdc++ version <12
        </td>
    </tr>

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

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

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

<pre>
    # tl;dr:
clang, starting from version 7.0.1 all the way up to the current trunk, in C++17 mode fails to compile the following code when combined with libstdc++ version <12:
https://godbolt.org/z/vrKc9877v
<details><summary>(click/tap to expand, this is the stripped minimal example that I could come up with that reproduces the problem)</summary>

```cpp
#include <vector>
#include <unordered_map>
#include <variant>
#include <type_traits>
#include <cstdint> // for uint8_t

namespace detail {
  template<typename Allocator, typename T>
  using ReboundAllocator = typename std::allocator_traits<Allocator>::template rebind_alloc<T>;
 template<typename T>
  using RemoveCVRef = std::remove_cv_t<std::remove_reference_t<T>>;
}

template<typename Allocator>
struct BasicValue {
  using Null = std::monostate;
 using Object = std::unordered_map<int, BasicValue,
    std::hash<int>, std::equal_to<int>,
    detail::ReboundAllocator<Allocator, std::pair<const int, BasicValue>>>;
  using Variant = std::variant<Null, Object>;

  BasicValue() = default;
  template<typename T,
 std::enable_if_t<!std::is_same_v<detail::RemoveCVRef<T>, BasicValue> &&
 std::is_convertible_v<T&&, Variant>, int> = 0>
  BasicValue(T &&v) noexcept(std::is_nothrow_constructible_v<Variant, T&&>) : m_data{ std::forward<T>(v) } {}

private:
  struct Workaround final {
 Workaround() noexcept { ::new(&storage) Variant{}; }
 template<typename... T>
    Workaround(T&&... v) noexcept(std::is_nothrow_constructible_v<Variant, T&&...>) {
 ::new(&storage) Variant{ std::forward<T>(v)... };
    }
 Workaround(const Workaround &other) { ::new(&storage) Variant{ other.operator const Variant & () }; }
    ~Workaround() {
 static_assert(sizeof(DummyVariant) == sizeof(Variant));
 static_assert(alignof(DummyVariant) == alignof(Variant));
      operator Variant&().~Variant();
    }
    auto &operator=(const Workaround &other) { return operator Variant & () = other.operator const Variant & (); }
    operator const Variant&() const& noexcept { return *std::launder(reinterpret_cast<const Variant*>(&storage)); }
    operator Variant&() & noexcept { return *std::launder(reinterpret_cast<Variant*>(&storage)); }

  private:
 using DummyUnorderedMap = std::unordered_map<int, int,
 std::hash<int>, std::equal_to<int>,
 detail::ReboundAllocator<Allocator, std::pair<const int, int>>>;
    using DummyVariant = std::variant<Null, DummyUnorderedMap>;
 alignas(DummyVariant) uint8_t storage[sizeof(DummyVariant)]{};
  } m_data;
};

// for some reason clang needs this
//static_assert(std::is_copy_constructible_v<BasicValue<std::allocator<char>>>);

using Value = BasicValue<std::allocator<char>>;


struct ShouldBeIrrelevant {
  // commenting any of the following lines gives:
 // "error: incomplete type 'std::unordered_map<...>"
  Value value;
 std::vector<int> bar;
};


int main() {
  Value v;
  const auto c = std::unordered_map<int, Value>{}; 

  //error: call to implicitly-deleted copy constructor of 'std::pair<const int, BasicValue<std::allocator<char>>>'
  v = c;
}
```
</details>
giving error

    error: call to implicitly-deleted copy constructor of 'std::pair<const int, BasicValue<std::allocator<char>>>'

while other compilers have no problems with this code, namely GCC and MSVC.

# Problem
## C++17 mode
Something breaks in clang (practically all versions supporting C++17 "enough", i.e. >7.0.1) with this code when it is used with libstdc++ version <12 (in particular versions 9.2..11.4, earlier versions do not support C++17 "enough")

If you remove the part
```cpp
struct ShouldBeIrrelevant {
  Value value;
  std::vector<int> bar;
};
```
or one or both of the members clang fails with error:

    error: incomplete type 'std::unordered_map<int, BasicValue<std::allocator<char>>>' used in type trait expression

though it seems completely irrelevant to the code that causes the error:
```cpp
Value v;
const auto c = std::unordered_map<int, Value>{};
v = c;
```

## Later standard modes
With e.g. C++20 or C++23, the error is spelled differently but is practically the same:

    error: no matching function for call to 'construct_at'

# Workaround
If I add a `static_assert`
```cpp
static_assert(std::is_copy_constructible_v<BasicValue<std::allocator<char>>>);
```
everythng starts to work as expected, and the `struct ShouldBeIrrelevant` snippet becomes truly irrelevant, i.e. removing it completely or removing any or both of the members has no effect.

# Context
In libstdc++ versions <12 `std::unordered_map` does not support incomplete types, we can work around that by using byte array storage, placement `::new()` to construct an object in that storage, and `reinterpret_cast` to turn it to a pointer to desired type inside implementation where the type is complete.

We _guess_ that alignment and size of some complete `std::unordered_map` instantiation is the same as the one with currently incomplete type, and `static_assert` that we guessed correctly in the destructor.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWd1z47YR_2vgl51wZNDWx4MfbDnu3LRpO0l6edSA5EpEDwRYAJRPecjf3lmA4IckX3yXTKc3HulEAIvf_vYDi6VwTh404gO7f2L3zzei87WxD950hxr1QWpEe1OY6vTAeA5esfypsix_ZItntngsldAHxrfgvLBe6gPsrWngiNZJo2GVLbJbEEqBrxFexQm6FrwJv8rOWtQevO30JxIhNWwZf2L86XYFjakQ9kIqR_NL07RSYVi3N0qZV9qqpDmvNWoaL6TGCl6lr0HJwvmqjLIGLCzf3vIBeO196-gXf2H85WCqwiifGXtg_OVXxl-O9q_lZr1aHeN0lm8r9ASH5d-zfOu6phH2RD_4ulSy_MT4ixdBOfzcCl2RRr6WDqQLsJ23sm2xgkZq2QgF-Fk0bdBJePgApelURYogcRT0CCMWW2uqrsQoprWmUNgwvmH5lvGXCZAINH4uF_GvbNv-Cc-lLlVXIRFxxNIbOy6aDXba2AotVrtGtG_MOQorhfZvjPpTiztvhfTujRml85UM6yFaAPbGQie1X-_8VBMtGnStKBEi_8BWT3EEwGPTKuGx35GmwqNSphSkHPGfnv48wADoHPnOj1iYTlfDdGD58zjf-Yp8I38UaXxQZzvuQJ5AkxIOsFhIXe3CIpZvw655gnsN7TVcjTni9uOPuA-QBiQ2DOzK486T_509trhHi7rEMBo3Hvdmq-cpp1_mLSFy3nalhyfhZPlRqA6n1Eewf--UmqNsjDbOB9lpbpz6j-LfWPr55DNH25JD8O1kR8a3aUMYl9XC1f1sCr_tOIL_6YTaeTMdHQVEB4ozz80_s-tUZCskDZZGOw-XAHueJ2bu9f0YA2Su8BA1W2KOREVaZrbqxUxZWDO-CZIq3ItO-clu171qUHukRotC4U7ug4MwfjuMSLdzosHdcchxiaLBE5NLnesOjC_p72wv6Xal0Ue0XtKex7A8zuTbxEwvLyWB_BkWk2CYaf9zv8-RaNAGP5fYesbX0w218bU1r7tgKHLcYeu0H99CQkFbE6GP0Owq4QVbPY3o98a-ClsNOq_Dtmz1HPx_HkmtlcdA_mC2Pmp-MfaTsORisJdaTNPWONQbNmlEcyBi0PgaBpfOGysOSNOSHhFE_gQDlmtOkGXZLLvAfN-eCZr1Z7GaZVkidtD1Pdr8DvMEMSo8qjJqPlMqBumEesaXxtdoe1DvgxNWZKZFG86FKHQIZ76EFI_nVgCA3y6MO3JBaVGWO-Ec2sCz_BXNnvH1c9c0p4HPEOgha6TxcSic-m_JE0oe9JcEjhPekBj-DYoPk5ZRley34cn6fNmMBNF5E6jvJdH27zCORd9ZfbH_jPL8-b3muTDN9RWDdvExrZ-FYw-K8cfBS5XodEWw1xal9mhbi35XCueHc2IQ_hj9eOZrXwR3AesPI_oqLAnRRV6Lh1pwrH-lU_sH0b7rPI9f54fEN53if9oR3gs-P7thqug7j_ALUmYiQ9AJdyUq-2IXkjXun97KCOz-ecj6CSmdR_3hNa3y5lXEpLR2dLGwKJzREC5toBErF64o08kXWWp2qLenK0fBtCTYXlbORH0t7Ej3JHfEz1QxhRozf4avEzjXeFq6_lTTneoJP1iLCo_BlmMJ25NTmqZBHa6uQp_A7M8umUpqdHCQR3RjOPRrGedoLSF6BKnpkqrQY7hGAOOrNwMjHZU8YYm6H6PKT-ehkm5rfThAQcq_bfTwKbWHRkh9cQylvSa-FCMjpO3yXRE91L5jLTJLH5GegZoyNAAMyKZVspRenb6rkJii-257gsGljCX-p8z9Xvn9Ln9bJVzHoF155V6U7svDbZ_xl8mFPzw9yCM5RFRrpi_A_5uu8fO1lgrjiZlaKNZBLY4I2qRWgkvNBulCR4W2pQpSneAv2y0IXcEPP33cZvPEksM_-05EekDP5v2bOPSTadDXxFxhUXxyIFMGYnzdWlF6SaSdQpuob9Y4cF3bmthRGoVSvGnTHWoKHcriGWbA8u9Dm4ncfK5J7A1JD9JB597RHSJEUkMrrJdlp4Qd8WwynmW3t9kd7YvCKomT0cqANj6BfhPxZsrhhz2cTAfxAh97O8L6t_o370ppV9PIN-SReTSQp2oEY6Ewvk4ZssGmIG-KpoydusBvCoU3Q-RrMuU3h0E0uNRxi9C8AfzcWnRksVk3pCb7kJs4pGhI4NQJ5MhyalqSW4W-XCk61_fkzjS-sN15xv3j-TbKuUhnZ1lsGpl_Ex4t3Rl0JWwVwrM_938JRssOWXJbviBbpx95bGT2WlIouRaVwgoquQ9NJ69OUHQhyqbhHJqeosEvuYI20Ahfhuyw73TpKRSpXElplPHVkDF3wp_lN1JscuNKYfUBRFWBALZczMuZgZkr4fU_LXvmhsIj2pOv9SF20UPH-9XYTyAc-SyWHkM7mVIxsRr0eiMdsOUCnJZtix4KLE1DPmq7mTMPqTPkHuJe-qnbGzuOhJroeuTXwpEBcb_H0l8cD1ujPX7u89kHfT3tupR3SaOrMbBcQGXQzdLrWQJxpM8rQil0T1u8YIYwLU59SV-cPIKwVpyGiptvoVWiRKr_CMK8PbChvcO7h97yIDSY2MakvELSJ5LIOGy5uLiBRSHhziZDGhHQmjCHflTopMUqZimpnawwlA4Bkwjh8FqjjedDnDRmqBnnvyDsDh06t4vQwsUjaEbI6GpB9gvXgIG9L9IuNWULLyOK9BZDNEhuSf-nQyFk_P5NDvnY3DITXs4DMYJ8RQiYQ3VkLZZRSBBfYSqUspvqIa82-Ubc4MPtarHZLO7XfHVTPyzv7orNiotyURWr8q4QFd7yu_2mWol7XN7lN_KBL_jdIl-sb_P7BV9l-e1yvy_W95v9HV9u7lfsboGNkCpT6thkxh5upHMdPqzv7tarGyUKVC68GuO8f9fF2f3zjX2g-d8V3cGxu4WSzrtRgpdehfdpccX98-WLrKNQsoqnidRHo0KsseUiXS-Xi0TchV1-r4i56ax6OHu9JX3dFVlpGsZfCGb_9V1rTeg_85egtWP8JSj-3wAAAP__0IW_mQ">