From 735ab86b811e40f1533ced98dfc4b7a0c09c545b Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 16 Dec 2020 11:59:57 -0800 Subject: [PATCH] PR47474: Add test for Clang's current behavior. Our current behavior rejects the example, following the current language rules, but it's likely the rules will be revised to allow this example. --- .../test/SemaCXX/cxx2a-destroying-delete.cpp | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/clang/test/SemaCXX/cxx2a-destroying-delete.cpp b/clang/test/SemaCXX/cxx2a-destroying-delete.cpp index 015d11e65526..46e5228ec6be 100644 --- a/clang/test/SemaCXX/cxx2a-destroying-delete.cpp +++ b/clang/test/SemaCXX/cxx2a-destroying-delete.cpp @@ -141,3 +141,29 @@ namespace templated { void operator delete(typename id_struct::type *, std::destroying_delete_t); // expected-error {{use 'D *'}} }; } + +namespace dtor_access { + struct S { + void operator delete(S *p, std::destroying_delete_t); + private: + ~S(); // expected-note {{here}} + }; + + // FIXME: PR47474: GCC accepts this, and it seems somewhat reasonable to + // allow, even though [expr.delete]p12 says this is ill-formed. + void f() { delete new S; } // expected-error {{calling a private destructor}} + + struct T { + void operator delete(T *, std::destroying_delete_t); + protected: + virtual ~T(); // expected-note {{here}} + }; + + struct U : T { + void operator delete(void *); + private: + ~U() override; + }; + + void g() { delete (T *)new U; } // expected-error {{calling a protected destructor}} +}