Clang Project

clang_source_code/test/SemaCXX/extended-usual-deallocation-functions.cpp
1// RUN: %clang_cc1 -fexceptions -std=c++2a -fsized-deallocation -fno-aligned-allocation -verify %s
2// RUN: %clang_cc1 -fexceptions -std=c++17 -fsized-deallocation -fno-aligned-allocation -verify %s
3// RUN: %clang_cc1 -fexceptions -std=c++14 -fsized-deallocation -faligned-allocation -DHAS_ALIGN -verify %s
4// RUN: %clang_cc1 -fexceptions -std=c++11 -fsized-deallocation -faligned-allocation -DHAS_ALIGN -verify %s
5
6// Test that we handle aligned deallocation, sized deallocation, and destroying
7// delete as usual deallocation functions even if they are used as extensions
8// prior to C++17.
9
10namespace std {
11using size_t = decltype(sizeof(0));
12enum class align_val_t : size_t;
13
14struct destroying_delete_t {
15  struct __construct { explicit __construct() = default; };
16  explicit destroying_delete_t(__construct) {}
17};
18
19inline constexpr destroying_delete_t destroying_delete(destroying_delete_t::__construct());
20}
21
22// FIXME: Should destroying delete really be on in all dialects by default?
23struct A {
24  void operator delete(void*) = delete;
25  void operator delete(A*, std::destroying_delete_t) = delete; // expected-note {{deleted}}
26};
27void ATest(A* a) { delete a; } // expected-error {{deleted}}
28
29struct B {
30  void operator delete(void*) = delete; // expected-note {{deleted}}
31  void operator delete(void*, std::size_t) = delete;
32};
33void BTest(B *b) { delete b; }// expected-error {{deleted}}
34
35
36struct alignas(128) C {
37#ifndef HAS_ALIGN
38  // expected-note@+2 {{deleted}}
39#endif
40  void operator delete(void*) = delete;
41#ifdef HAS_ALIGN
42  // expected-note@+2 {{deleted}}
43#endif
44  void operator delete(void*, std::align_val_t) = delete;
45};
46void CTest(C *c) { delete c; } // expected-error {{deleted}}
47
48struct D {
49  void operator delete(void*) = delete;
50  void operator delete(D*, std::destroying_delete_t) = delete; // expected-note {{deleted}}
51  void operator delete(D*, std::destroying_delete_t, std::size_t) = delete;
52  void operator delete(D*, std::destroying_delete_t, std::align_val_t) = delete;
53  void operator delete(D*, std::destroying_delete_t, std::size_t, std::align_val_t) = delete;
54};
55void DTest(D *d) { delete d; } // expected-error {{deleted}}
56
57struct alignas(128) E {
58  void operator delete(void*) = delete;
59  void operator delete(E*, std::destroying_delete_t) = delete;
60  void operator delete(E*, std::destroying_delete_t, std::size_t) = delete;
61  void operator delete(E*, std::destroying_delete_t, std::align_val_t) = delete;
62  void operator delete(E*, std::destroying_delete_t, std::size_t, std::align_val_t) = delete;
63#ifdef HAS_ALIGN
64  // expected-note@-3 {{deleted}}
65#else
66  // expected-note@-7 {{deleted}}
67#endif
68};
69void ETest(E *e) { delete e; } // expected-error {{deleted}}
70