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

    <tr>
        <th>Summary</th>
        <td>
            [C++20] [Modules] Modules don't take care of generated allocators and the included allocators well 
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            c++20,
            clang:modules
      </td>
    </tr>

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

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

<pre>
    Here is the example:

```C++
// base.cppm
export module base;

export struct Base {
    virtual void hello() = 0;
    virtual ~Base() = default;
};


// derived.cppm
module;
#include <iostream>
export module derived;
export import base;

export class Derived : public Base {
public:
    void hello() override {
        std::cout << "hello from derived\n";
    }
};
```

Now let's compile them with:

```
clang++ -std=c++20 base.cppm --precompile -o base.pcm
clang++ -std=c++20 derived.cppm --precompile -o derived.pcm -fmodule-file=base.pcm
```

then we'll see the errors like:

```
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/new:88:14: error: declaration of 'align_val_t' in the global module follows declaration in module base
  enum class align_val_t: size_t {};
             ^
note: previous declaration is here
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/new:125:26: error: declaration of 'operator new' in the global module follows declaration in module base
_GLIBCXX_NODISCARD void* operator new(std::size_t) _GLIBCXX_THROW (std::bad_alloc)
                         ^
note: previous declaration is here
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/new:127:26: error: declaration of 'operator new[]' in the global module follows declaration in module base
_GLIBCXX_NODISCARD void* operator new[](std::size_t) _GLIBCXX_THROW (std::bad_alloc)
                         ^
note: previous declaration is here
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/new:129:6: error: declaration of 'operator delete' in the global module follows declaration in module base
void operator delete(void*) _GLIBCXX_USE_NOEXCEPT
     ^
note: previous declaration is here
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/new:131:6: error: declaration of 'operator delete[]' in the global module follows declaration in module base
void operator delete[](void*) _GLIBCXX_USE_NOEXCEPT
     ^
note: previous declaration is here
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/new:148:26: error: declaration of 'operator new' in the global module follows declaration in module base
_GLIBCXX_NODISCARD void* operator new(std::size_t, std::align_val_t)
                         ^
note: previous declaration is here
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/new:152:6: error: declaration of 'operator delete' in the global module follows declaration in module base
void operator delete(void*, std::align_val_t)
     ^
note: previous declaration is here
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/new:156:26: error: declaration of 'operator new[]' in the global module follows declaration in module base
_GLIBCXX_NODISCARD void* operator new[](std::size_t, std::align_val_t)
                         ^
note: previous declaration is here
/usr/lib/gcc/x86_64-redhat-linux/9/../../../../include/c++/9/new:160:6: error: declaration of 'operator delete[]' in the global module follows declaration in module base
void operator delete[](void*, std::align_val_t)
     ^
note: previous declaration is here
```

It tells that the operator new/delete declaration in the module base follows the operator new/delete declarations in the global module fragment in the module derived. Then it violates the corresponding language rule. The problem here is that there is no `operator new/delete` in the module base. What happened?

The reason is that the allocation/deallocation function is special. The compiler would create them automatically if the compiler failed to find them. So it shows that we didn't take care of the creation of such allocation/deallocation functions (historically) so here shows the conflicting.

The workaround could include the `<new>` in the GMF of base:

```
// base.cppm
module;
#include <new>
export module base;

export struct Base {
    virtual void hello() = 0;
    virtual ~Base() = default;
};


// derived.cppm
module;
#include <iostream>
export module derived;
export import base;

export class Derived : public Base {
public:
    void hello() override {
        std::cout << "hello from derived\n";
    }
};
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztWFuT2jYU_jXmRQMDtsHwwMNy2SQzTdLJbif7xsiWjNWVLVeSYdNf36OLwbBss23azG5Txghs6dy-c5F1UkG-zN9SSRFTSBcU0Qdc1pwG0VUwXAXDdpwM3bUMwoW53NPwGi6UYkUHWV2X7il9qIXUqBSk4dROBtGiy8wvUFo2mUYLWICCxK9A8NkxqRvM0U4wggrKuQjCaRDOUBCt0PDArLs0SNaGT2cdoTluuD6KTlZnapzYQKhkO0o6Zjj9jzRhxKqMNwSUjZZMgPYUl0G0vmS053Yg9rOstD9PQ5JxrBRaOWqQc4XqJuUsOwPJPTy4yAJxjpXYUSkZOYPWfJQmhjS6ykSjjTFwoSAMLTXKpSgP-o-XFUycIG5wfAxoGx5dmz6IPeJUB2GiUCbKmgEwEGEl2jNdPBVf7hZwqLYu0lDf6rvK3G04PIYb6vdrSVvWfeFm6qx8BpOuvx_xaSeBFernzqf9nJloWJ3KuGg4GFmhPQRjwjlSlLq8klJIhTi7fzK3DgHZKAkjZymM2wyUvn6YTjaTuC8pKbDuc1Y1D_B0Bt_B4PHgAxX-eYP92oruQfZ0CsMoNtFllTJ_CAW0JNZMVEjkEA0J5mxbbXaYb4wHEausFVsuUkg3H-a5gIjZqxNqWNjNfB83tGpKH91dxiBZsd_pRtso7QQU6n6CsU-ySmhqk0LSHRPNmWAF8S_pdwJxFI5hDCdfQVHUFO6FRIbqW2HcvPnp3WJ5d7f58HH17mZ59Wll0z4Ir9CpnOkhxR26ph4ciG_ffvr4GXUXpZhsMKgAds4uwP_yXZH8ZVeMF8F49d0c4qX9aG6ZwfhsrxAKewX9ZpfYffAR06l3ywniv9yswXHru-X659sOvi8Sy2j0N7D8Z4L8IqJtRL92XOPpa6riy-O728n2_CrLwzh8geXhOQi_TDQnr3UP_E8FNbzEv-w6_W8F-KVz0DuNNJwpTV8Ba2vZaYG7dkqeW2YWdqw7APAsBuoJECXelrTSZ_zbgx66NUc2phGYybGmTlgmpKSqFhVh1RaZ02SDtxRJoLQUgItIORxoi0P_xNnp7iqBAJCLGsPzC5YO0GfDoMB1TSvTPbjuomkESoqVg_4AqX1DtKZb7sdblDdV1npK1TRjmDu1_UlXor1oOEEZcNX-aI4bLUogz4DPF8Ryj4Nfn2P4IUgLlLOKWIoBuhEGOFU4F4FWe8CVEVAnAQ3xPdBjAER4XkaYTwXVZMUz9FfmrbhgCkB0epm3DSUc6q1co2WVcwYU1XZwjtteyHssRQNKZ9bmtpVjCE3URkubwOuOY968vzZKumbNVw7sF7pgf9o-8sL-b5f94O2yHp2PJpNpPArjUdQj84jMohnuaaY5nUPxXrb9KqjiUJYX7y1eytz5v4iIC5m2hfoBVQdA8flkWk_YpWwb-ydzezAG9RrJ54XWtTIGW0dvmS6adAAVwOyafNf-9KH0_UozbXZEpRpQKbweT2fJuFfM8zRM6TAOaR6RdBjPhnkeZkkSxnk-IzEYzXFKuTL2AVqHlpxBLrTIusZd5ENKmYnxqsfm4TAMR6NRPEzGURQNphGNYxLOIpqMQDQN4iEtoUINjIIDIbc9Obe6ps1WwSSHEqKOkxA6sP9R6vVYFg2ufmN3zczLg1JYCDk_Pu9ZS-fWzD8AOycY7Q">