// RUN: %clang_cc1 %s -verify=expected,noms -fsyntax-only -triple=x86_64-unknown-linux-gnu // RUN: %clang_cc1 %s -verify=expected,noms -fsyntax-only -triple=x86_64-unknown-linux-gnu -std=c++20 // RUN: %clang_cc1 %s -verify=expected,ms -fms-extensions -fms-compatibility -triple=x86_64-pc-windows-msvc -DMS // Verify that clang doesn't emit additional errors when searching for // additional operators delete for vector deleting destructors support. struct Foo { virtual ~Foo() {} // expected-error {{attempt to use a deleted function}} static void operator delete(void* ptr) = delete; // expected-note {{explicitly marked deleted here}} }; struct Bar { virtual ~Bar() {} static void operator delete[](void* ptr) = delete; }; struct Baz { virtual ~Baz() {} static void operator delete[](void* ptr) = delete; // expected-note {{explicitly marked deleted here}} }; struct BarBaz { ~BarBaz() {} static void operator delete[](void* ptr) = delete; }; void foobar() { Baz *B = new Baz[10](); delete [] B; // expected-error {{attempt to use a deleted function}} BarBaz *BB = new BarBaz[10](); } struct BaseDelete1 { void operator delete[](void *); }; struct BaseDelete2 { void operator delete[](void *); }; struct BaseDestructor { BaseDestructor() {} virtual ~BaseDestructor() = default; }; struct Final : BaseDelete1, BaseDelete2, BaseDestructor { Final() {} }; struct FinalExplicit : BaseDelete1, BaseDelete2, BaseDestructor { FinalExplicit() {} inline ~FinalExplicit() {} }; #ifdef MS struct Final1 : BaseDelete1, BaseDelete2, BaseDestructor { __declspec(dllexport) ~Final1() {} }; #endif // MS // Make sure there is no double diagnosing for declared-only destructors and // new[]. struct DeclaredOnly { virtual ~DeclaredOnly(); // ms-error {{attempt to use a deleted function}} static void operator delete(void* ptr) = delete; // ms-note {{explicitly marked deleted here}} }; struct DeclaredOnlyArr { virtual ~DeclaredOnlyArr(); static void operator delete[](void* ptr) = delete; }; void foo() { Final* a = new Final[10](); FinalExplicit* b = new FinalExplicit[10](); DeclaredOnly *d = new DeclaredOnly[5](); DeclaredOnlyArr *e = new DeclaredOnlyArr[5](); } // Make sure there is no double diagnosing for forward declared destructors // and new[]. namespace std { struct destroying_delete_t {}; } struct A { void operator delete( A*, //expected-error {{cannot cast 'D' to its private base class 'A'}} std::destroying_delete_t); }; struct B : private A { using A::operator delete; }; //expected-note {{declared private here}} struct D : B { virtual ~D(); }; //ms-note {{while checking implicit 'delete this' for virtual destructor}} void f() { new D[5]; } D::~D() {} // noms-note {{while checking implicit 'delete this' for virtual destructor}}