libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

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 }