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

    <tr>
        <th>Summary</th>
        <td>
            The preferred global deallocation for the array whose element is of class type with non-trival destructor
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    ````cpp
void* operator new[](std::size_t N){
    auto ptr = malloc(sizeof(char)* N);
    std::cout<<"new\n";
    return ptr;
}
void operator delete[](void* ptr,std::size_t N) noexcept{  // #1
    std::cout<<"delete\n";
    free(ptr);
}

struct A{
  ~A(){}
};
int main(){
   auto ptr = new A[2];
   delete [] ptr;
}
````
The found deallocation for the delete-expression should be `#1` and these implicitly declared ones in global scope
>  - void operator delete[](void*) noexcept;
> - void operator delete[](void*, std::align_val_t) noexcept;
> - void operator delete[](void*, std::size_t, std::align_val_t) noexcept;

In this example, clang does not select `#1` but it should be the preferred one as per [expr.delete] p10
> If more than one deallocation function is found, the function to be called is selected as follows: 
>> - [...]
>> - If the deallocation functions **belong to a class scope**, the one without a parameter of type std​::​size_­t is selected.
>> - If the type is complete and if, for an array delete expression only, the operand is a pointer to a class type with a non-trivial destructor or a (possibly multi-dimensional) array thereof, the function with a parameter of type std​::​size_­t is selected.  

The second bullet does not apply here since the found declarations belong to global scope. The third bullet should apply here. For single object delete expression, clang also does not select the one with `std::size_t` but it should be.

````cpp
void* operator new(std::size_t N){
    auto ptr = malloc(sizeof(char)* N);
    std::cout<<"single new "<< (long long int) ptr<<std::endl;
    return ptr;
}

void operator delete(void* ptr,std::size_t N) noexcept{
    std::cout<<"single delete "<< (long long int) ptr<<std::endl;
    free(ptr);
}
struct A{
  // ~A(){}
};
int main(){
    auto p = new A;
    delete p;
}
````
The one with parameter `std::size_t` should be selected regardless of whether the destructor of `A` is trivial or non-trivial according to third bullet. GCC is correct in two cases https://godbolt.org/z/5G41dP3P8
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzFVstu2zoQ_Rp5Q0SwJT8XWjh2WnRTdNF9QEm0zQuaFEgqTvr1PUM9nRitixa4gSJLImfmzJkXc1O-ZdFy2l9FVUXTfTTdvhhZRsmWmUpY7o1lWlyixWO02EfJ2vkySre4nPwhnj37GiWbaPXYSDL88dobVnnLonTPzlwpU5AYdpsDHooTtyQC_UE0HYn2ugtT-yjd0ZUkwfpO4-lqsxW-tpos9Z-j1X7wYIBfCiW86D3o3CPJZHfLH6aNeC1E5eEYY1HyCRd-0tnvoHaWPqI9WCFgO9jcfATc3J23deHZdsRntHraQq4lud-Oh06H1B40Sz3s6oxeRQIsQvHiMSESRsgayKxh5zab4yRpvnw_CXYwtS4hHiLMvTQanyzzWGp0PojXygrnaMWdTK1KlsMQdBCTyynjkMd2J5g8V0oW0qs3yBaKW4HwaeGY1OyoTM4VcwXi2eJJnxh7YPcE-SqYvWOQv1d8N0SaK3nUzy9cPft_qbbJuz-zFO5fNNiTjolXDvoEaQB1-shKA-a08czBOvJpRHleeyb9KBwULkTpIGzLOeOOAT0lBMUv7jxAbsymg6NfDuxsLMlzHcSuE6HWRXgAvJAnBI5M9QvITFgvIAOz2NVAxTMnCWi6OBDBeoMNuQAVxzFxef0daJq8u4HBscD4NhfKgBwY5sSTc21KhcUOH3lykR70eGyruOVneG-ZgYG3SoQQPSXRehqtH5tY9a8hjtEuibZ7P_Yovo01qMO2wlDwUIFUDfJAQKiMwCq3lr919TmqJaPVW4-XEk0HBgHXoBcA7MjFYIUcwhdt9IO38kWimkrR9BpYImOMWpOB-hwVeK6Vlw-lPAtN9riiHGzAwKQNbfxdNFsL_4YvxsZZTq3GicLAybxGtvghvXlVAS5BYk7qoknmri1RF-FN_IfIj3tJzEg1Ksj2mtuyGPTG7BPogfKjAtf5f1RNHwIyFB5XznyovnFaUSm-L_wbVRmPCbh_RP8fw7nlhqZLGHn0mbIpMB5uyElKoDBZaLXXI3Sp7p7ov5jrfzrR73SpG4x_69VvJv-tmd8eOP5i9LeBHk3-MaTWtereUd-n71DgtxN5mCt9P7fiyG2pUCrUFC4nQT2k7dZDDzqQQrJOnaBrUpTWo57Fi8LYUjaVPK7bmH3e7ZpeiikGMnFq8BeD6eJQiifvK5olDatHU-ZG-djYI95-4H_xeT4rv6Xf1hORzZbL1Xw9X6yWkzJLy0264ROPY4nIvl_NybaP3Dz8NJ3ycjI414AEdNHQ3uDi-5bcOXfVjye1Vdk7zNhc5zEmBV6Ueul-HiprqCXhVTpXC0ferFfr5eSUbZZrgF3Am3W-2qzzdJrOymQxX2yK5XpVbCaKoy26jI4m4YjNggrK9sV-IrNkmiSzGYTm0026xCngkPP5LBHLWXpIRRLNpwKZp2LCQWRObBYg5fXRYVFJ592wCL9xohEia05CE2Tnydjs9XyaLmazSTCdBeg_AeAO3T4">