Home | History | Annotate | Download | only in new.delete.single
      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 // UNSUPPORTED: c++98, c++03, c++11, c++14
     11 // UNSUPPORTED: sanitizer-new-delete
     12 
     13 // Aligned allocation was not provided before macosx10.12 and as a result we
     14 // get availability errors when the deployment target is older than macosx10.13.
     15 // However, AppleClang 10 (and older) don't trigger availability errors.
     16 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.12
     17 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.11
     18 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.10
     19 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.9
     20 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.8
     21 // XFAIL: !(apple-clang-9 || apple-clang-10) && availability=macosx10.7
     22 
     23 // On AppleClang 10 (and older), instead of getting an availability failure
     24 // like above, we get a link error when we link against a dylib that does
     25 // not export the aligned allocation functions.
     26 // XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.12
     27 // XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.11
     28 // XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.10
     29 // XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.9
     30 // XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.8
     31 // XFAIL: (apple-clang-9 || apple-clang-10) && with_system_cxx_lib=macosx10.7
     32 
     33 // NOTE: gcc doesn't provide -faligned-allocation flag to test for
     34 // XFAIL: no-aligned-allocation && !gcc
     35 
     36 // On Windows libc++ doesn't provide its own definitions for new/delete
     37 // but instead depends on the ones in VCRuntime. However VCRuntime does not
     38 // yet provide aligned new/delete definitions so this test fails.
     39 // XFAIL: LIBCXX-WINDOWS-FIXME
     40 
     41 // test operator new nothrow by replacing only operator new
     42 
     43 #include <new>
     44 #include <cstddef>
     45 #include <cstdlib>
     46 #include <cassert>
     47 #include <limits>
     48 
     49 #include "test_macros.h"
     50 
     51 constexpr auto OverAligned = __STDCPP_DEFAULT_NEW_ALIGNMENT__ * 2;
     52 
     53 bool A_constructed = false;
     54 
     55 struct alignas(OverAligned) A
     56 {
     57     A() {A_constructed = true;}
     58     ~A() {A_constructed = false;}
     59 };
     60 
     61 bool B_constructed = false;
     62 
     63 struct B {
     64   std::max_align_t  member;
     65   B() { B_constructed = true; }
     66   ~B() { B_constructed = false; }
     67 };
     68 
     69 int new_called = 0;
     70 alignas(OverAligned) char Buff[OverAligned * 2];
     71 
     72 void* operator new(std::size_t s, std::align_val_t a) TEST_THROW_SPEC(std::bad_alloc)
     73 {
     74     assert(!new_called);
     75     assert(s <= sizeof(Buff));
     76     assert(static_cast<std::size_t>(a) == OverAligned);
     77     ++new_called;
     78     return Buff;
     79 }
     80 
     81 void  operator delete(void* p, std::align_val_t a) TEST_NOEXCEPT
     82 {
     83     assert(p == Buff);
     84     assert(static_cast<std::size_t>(a) == OverAligned);
     85     assert(new_called);
     86     --new_called;
     87 }
     88 
     89 
     90 int main()
     91 {
     92     {
     93         A* ap = new (std::nothrow) A;
     94         assert(ap);
     95         assert(A_constructed);
     96         assert(new_called);
     97         delete ap;
     98         assert(!A_constructed);
     99         assert(!new_called);
    100     }
    101     {
    102         B* bp = new (std::nothrow) B;
    103         assert(bp);
    104         assert(B_constructed);
    105         assert(!new_called);
    106         delete bp;
    107         assert(!new_called);
    108         assert(!B_constructed);
    109     }
    110 }
    111