brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.8 KiB · 812fd78 Raw
199 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -fexceptions -verify %s2// RUN: %clang_cc1 -std=c++2a  -verify %s3 4namespace std {5  using size_t = decltype(sizeof(0));6  enum class align_val_t : size_t;7 8  struct destroying_delete_t {9    struct __construct { explicit __construct() = default; };10    explicit destroying_delete_t(__construct) {}11  };12 13  inline constexpr destroying_delete_t destroying_delete(destroying_delete_t::__construct());14}15 16void operator delete(void*, std::destroying_delete_t); // ok, just a placement delete17 18struct A;19void operator delete(A*, std::destroying_delete_t); // expected-error {{1st parameter of 'operator delete' must have type 'void *'}}20 21struct A {22  void operator delete(A*, std::destroying_delete_t);23  void operator delete(A*, std::destroying_delete_t, std::size_t);24  void operator delete(A*, std::destroying_delete_t, std::align_val_t);25  void operator delete(A*, std::destroying_delete_t, std::size_t, std::align_val_t);26  void operator delete(A*, std::destroying_delete_t, int); // expected-error {{destroying operator delete can have only an optional size and optional alignment parameter}}27  // FIXME: It's probably a language defect that we permit usual operator delete to be variadic.28  void operator delete(A*, std::destroying_delete_t, std::size_t, ...);29 30  void operator delete(struct X*, std::destroying_delete_t, std::size_t, ...); // expected-error {{1st parameter of destroying 'operator delete' must have type 'A *'}}31 32  void operator delete(void*, std::size_t);33};34 35void delete_A(A *a) { delete a; }36 37namespace convert_param {38  struct A {39    void operator delete(40        A*,41        std::destroying_delete_t);42  };43  struct B : private A { using A::operator delete; }; // expected-note 2{{declared private here}}44  struct C : B {};45  void delete_C(C *c) { delete c; } // expected-error {{cannot cast 'C' to its private base class 'A'}}46 47  // expected-error@-7 {{cannot cast 'convert_param::D' to its private base class 'A'}}48  struct D : B { virtual ~D() {} }; // expected-note {{while checking implicit 'delete this' for virtual destructor}}49}50 51namespace delete_selection {52  struct B {53    void operator delete(void*) = delete;54    void operator delete(B *, std::destroying_delete_t) = delete; // expected-note {{deleted}}55  };56  void delete_B(B *b) { delete b; } // expected-error {{deleted}}57 58  struct C {59    C();60    void *operator new(std::size_t);61    void operator delete(void*) = delete; // expected-note 0-1 {{deleted here}}62    void operator delete(C *, std::destroying_delete_t) = delete;63  };64  // TODO: We only diagnose the use of a deleted operator delete when exceptions65  // are enabled. Otherwise we don't bother doing the lookup.66#ifdef __EXCEPTIONS67  // expected-error@+2 {{attempt to use a deleted function}}68#endif69  C *new_C() { return new C; }70 71  struct D {72    void operator delete(D *, std::destroying_delete_t) = delete; // expected-note {{deleted}}73    void operator delete(D *, std::destroying_delete_t, std::align_val_t) = delete;74  };75  void delete_D(D *d) { delete d; } // expected-error {{deleted}}76 77  struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) E {78    void operator delete(E *, std::destroying_delete_t) = delete;79    void operator delete(E *, std::destroying_delete_t, std::align_val_t) = delete; // expected-note {{deleted}}80  };81  void delete_E(E *e) { delete e; } // expected-error {{deleted}}82 83  struct F {84    void operator delete(F *, std::destroying_delete_t) = delete; // expected-note {{deleted}}85    void operator delete(F *, std::destroying_delete_t, std::size_t) = delete;86  };87  void delete_F(F *f) { delete f; } // expected-error {{deleted}}88 89  struct G {90    void operator delete(G *, std::destroying_delete_t, std::align_val_t) = delete;91    void operator delete(G *, std::destroying_delete_t, std::size_t) = delete; // expected-note {{deleted}}92  };93  void delete_G(G *g) { delete g; } // expected-error {{deleted}}94 95  struct H {96    void operator delete(H *, std::destroying_delete_t, std::align_val_t) = delete; // expected-note {{deleted}}97    void operator delete(H *, std::destroying_delete_t, std::size_t, std::align_val_t) = delete;98  };99  void delete_H(H *h) { delete h; } // expected-error {{deleted}}100 101  struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2) I {102    void operator delete(I *, std::destroying_delete_t, std::size_t) = delete;103    void operator delete(I *, std::destroying_delete_t, std::size_t, std::align_val_t) = delete; // expected-note {{deleted}}104  };105  void delete_I(I *i) { delete i; } // expected-error {{deleted}}106}107 108namespace first_param_conversion {109  struct A {110    void operator delete(A *, std::destroying_delete_t);111  };112  void f(const volatile A *a) {113    delete a; // ok114  }115 116  struct B {117    void operator delete(B *, std::destroying_delete_t);118  };119  struct C : B {};120  struct D : B {};121  struct E : C, D {};122  void g(E *e) {123    delete e; // expected-error {{ambiguous conversion from derived class 'E' to base class 'B':}}124  }125}126 127namespace templated {128  template<typename T> using id_alias = T;129  template<typename T> struct id_struct { using type = T; };130 131  template<typename T> struct A {132    void operator delete(A *, std::destroying_delete_t);133  };134  template<typename T> struct B {135    void operator delete(B<T> *, std::destroying_delete_t);136  };137  template<typename T> struct C {138    void operator delete(id_alias<C> *, std::destroying_delete_t);139  };140  template<typename T> struct D {141    void operator delete(typename id_struct<D>::type *, std::destroying_delete_t); // expected-error {{use 'templated::D<T> *'}}142  };143}144 145namespace dtor_access {146  struct S {147    void operator delete(S *p, std::destroying_delete_t);148  private:149    ~S();150  };151 152  // C++20 [expr.delete]p12 says this is ill-formed, but GCC accepts and we153  // filed CWG2889 to resolve in the same way.154  void f() { delete new S; }155 156  struct T {157    void operator delete(T *, std::destroying_delete_t);158  protected:159    virtual ~T(); // expected-note {{here}}160  };161 162  struct U : T {163    void operator delete(void *);164  private:165    ~U() override;166  };167 168  void g() { delete (T *)new U; } // expected-error {{calling a protected destructor of class 'T'}}169}170 171namespace delete_from_new {172  struct A {173    A(); // might throw174    void operator delete(A *, std::destroying_delete_t) = delete;175  };176  struct B {177    B(); // might throw178    void operator delete(void *) = delete; // #member-delete-from-new179    void operator delete(B *, std::destroying_delete_t) = delete;180  };181  void f() {182    new A; // calls ::operator delete183    new B; // calls B::operator delete184#ifdef __EXCEPTIONS185  // expected-error@-2 {{attempt to use a deleted function}}186  // expected-note@#member-delete-from-new {{deleted here}}187#endif188  }189}190 191namespace GH96191 {192  struct S {};193  struct T {194    void operator delete(S) { } // expected-error {{1st parameter of 'operator delete' must have type 'void *'}}195  };196 197  void foo(T *t) { delete t; }198}199