libcpp_deallocate.sh.cpp (6520B)
1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // test libc++'s implementation of align_val_t, and the relevant new/delete 11 // overloads in all dialects when -faligned-allocation is present. 12 13 // Libc++ defers to the underlying MSVC library to provide the new/delete 14 // definitions, which does not yet provide aligned allocation 15 // XFAIL: LIBCXX-WINDOWS-FIXME 16 17 // The dylibs shipped before macosx10.14 do not contain the aligned allocation 18 // functions, so trying to force using those with -faligned-allocation results 19 // in a link error. 20 // XFAIL: with_system_cxx_lib=macosx10.13 21 // XFAIL: with_system_cxx_lib=macosx10.12 22 // XFAIL: with_system_cxx_lib=macosx10.11 23 // XFAIL: with_system_cxx_lib=macosx10.10 24 // XFAIL: with_system_cxx_lib=macosx10.9 25 // XFAIL: with_system_cxx_lib=macosx10.8 26 // XFAIL: with_system_cxx_lib=macosx10.7 27 28 // The test will fail on deployment targets that do not support sized deallocation. 29 // XFAIL: availability=macosx10.11 30 // XFAIL: availability=macosx10.10 31 // XFAIL: availability=macosx10.9 32 // XFAIL: availability=macosx10.8 33 // XFAIL: availability=macosx10.7 34 35 // XFAIL: sanitizer-new-delete, ubsan 36 37 // GCC doesn't support the aligned-allocation flags. 38 // XFAIL: gcc 39 40 // RUN: %build -faligned-allocation -fsized-deallocation 41 // RUN: %run 42 // RUN: %build -faligned-allocation -fno-sized-deallocation -DNO_SIZE 43 // RUN: %run 44 // RUN: %build -fno-aligned-allocation -fsized-deallocation -DNO_ALIGN 45 // RUN: %run 46 // RUN: %build -fno-aligned-allocation -fno-sized-deallocation -DNO_ALIGN -DNO_SIZE 47 // RUN: %run 48 49 #include <new> 50 #include <typeinfo> 51 #include <string> 52 #include <cassert> 53 54 #include "test_macros.h" 55 56 struct alloc_stats { 57 alloc_stats() { reset(); } 58 59 int aligned_sized_called; 60 int aligned_called; 61 int sized_called; 62 int plain_called; 63 int last_size; 64 int last_align; 65 66 void reset() { 67 aligned_sized_called = aligned_called = sized_called = plain_called = 0; 68 last_align = last_size = -1; 69 } 70 71 bool expect_plain() const { 72 assert(aligned_sized_called == 0); 73 assert(aligned_called == 0); 74 assert(sized_called == 0); 75 assert(last_size == -1); 76 assert(last_align == -1); 77 return plain_called == 1; 78 } 79 80 bool expect_size(int n) const { 81 assert(plain_called == 0); 82 assert(aligned_sized_called == 0); 83 assert(aligned_called == 0); 84 assert(last_size == n); 85 assert(last_align == -1); 86 return sized_called == 1; 87 } 88 89 bool expect_align(int a) const { 90 assert(plain_called == 0); 91 assert(aligned_sized_called == 0); 92 assert(sized_called == 0); 93 assert(last_size == -1); 94 assert(last_align == a); 95 return aligned_called == 1; 96 } 97 98 bool expect_size_align(int n, int a) const { 99 assert(plain_called == 0); 100 assert(sized_called == 0); 101 assert(aligned_called == 0); 102 assert(last_size == n); 103 assert(last_align == a); 104 return aligned_sized_called == 1; 105 } 106 }; 107 alloc_stats stats; 108 109 void operator delete(void* p)TEST_NOEXCEPT { 110 ::free(p); 111 stats.plain_called++; 112 stats.last_size = stats.last_align = -1; 113 } 114 115 #ifndef NO_SIZE 116 void operator delete(void* p, size_t n)TEST_NOEXCEPT { 117 ::free(p); 118 stats.sized_called++; 119 stats.last_size = n; 120 stats.last_align = -1; 121 } 122 #endif 123 124 #ifndef NO_ALIGN 125 void operator delete(void* p, std::align_val_t a)TEST_NOEXCEPT { 126 ::free(p); 127 stats.aligned_called++; 128 stats.last_align = static_cast<int>(a); 129 stats.last_size = -1; 130 } 131 132 void operator delete(void* p, size_t n, std::align_val_t a)TEST_NOEXCEPT { 133 ::free(p); 134 stats.aligned_sized_called++; 135 stats.last_align = static_cast<int>(a); 136 stats.last_size = n; 137 } 138 #endif 139 140 void test_libcpp_dealloc() { 141 void* p = nullptr; 142 size_t over_align_val = TEST_ALIGNOF(std::max_align_t) * 2; 143 size_t under_align_val = TEST_ALIGNOF(int); 144 size_t with_size_val = 2; 145 146 { 147 std::__libcpp_deallocate_unsized(p, under_align_val); 148 assert(stats.expect_plain()); 149 } 150 stats.reset(); 151 152 #if defined(NO_SIZE) && defined(NO_ALIGN) 153 { 154 std::__libcpp_deallocate(p, with_size_val, over_align_val); 155 assert(stats.expect_plain()); 156 } 157 stats.reset(); 158 #elif defined(NO_SIZE) 159 { 160 std::__libcpp_deallocate(p, with_size_val, over_align_val); 161 assert(stats.expect_align(over_align_val)); 162 } 163 stats.reset(); 164 #elif defined(NO_ALIGN) 165 { 166 std::__libcpp_deallocate(p, with_size_val, over_align_val); 167 assert(stats.expect_size(with_size_val)); 168 } 169 stats.reset(); 170 #else 171 { 172 std::__libcpp_deallocate(p, with_size_val, over_align_val); 173 assert(stats.expect_size_align(with_size_val, over_align_val)); 174 } 175 stats.reset(); 176 { 177 std::__libcpp_deallocate_unsized(p, over_align_val); 178 assert(stats.expect_align(over_align_val)); 179 } 180 stats.reset(); 181 { 182 std::__libcpp_deallocate(p, with_size_val, under_align_val); 183 assert(stats.expect_size(with_size_val)); 184 } 185 stats.reset(); 186 #endif 187 } 188 189 struct TEST_ALIGNAS(128) AlignedType { 190 AlignedType() : elem(0) {} 191 TEST_ALIGNAS(128) char elem; 192 }; 193 194 void test_allocator_and_new_match() { 195 stats.reset(); 196 #if defined(NO_SIZE) && defined(NO_ALIGN) 197 { 198 int* x = new int(42); 199 delete x; 200 assert(stats.expect_plain()); 201 } 202 stats.reset(); 203 { 204 AlignedType* a = new AlignedType(); 205 delete a; 206 assert(stats.expect_plain()); 207 } 208 stats.reset(); 209 #elif defined(NO_SIZE) 210 stats.reset(); 211 #if TEST_STD_VER >= 11 212 { 213 int* x = new int(42); 214 delete x; 215 assert(stats.expect_plain()); 216 } 217 #endif 218 stats.reset(); 219 { 220 AlignedType* a = new AlignedType(); 221 delete a; 222 assert(stats.expect_align(TEST_ALIGNOF(AlignedType))); 223 } 224 stats.reset(); 225 #elif defined(NO_ALIGN) 226 stats.reset(); 227 { 228 int* x = new int(42); 229 delete x; 230 assert(stats.expect_size(sizeof(int))); 231 } 232 stats.reset(); 233 { 234 AlignedType* a = new AlignedType(); 235 delete a; 236 assert(stats.expect_size(sizeof(AlignedType))); 237 } 238 stats.reset(); 239 #else 240 stats.reset(); 241 { 242 int* x = new int(42); 243 delete x; 244 assert(stats.expect_size(sizeof(int))); 245 } 246 stats.reset(); 247 { 248 AlignedType* a = new AlignedType(); 249 delete a; 250 assert(stats.expect_size_align(sizeof(AlignedType), 251 TEST_ALIGNOF(AlignedType))); 252 } 253 stats.reset(); 254 #endif 255 } 256 257 int main() { 258 test_libcpp_dealloc(); 259 test_allocator_and_new_match(); 260 }