cxa_vec_new_overflow_PR41395.pass.cpp
1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: no-exceptions 10 11 // PR41395 isn't fixed until the dylib shipped with macOS 10.15 12 // XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12|13|14}} 13 14 #include "cxxabi.h" 15 #include <new> 16 #include <cassert> 17 18 void dummy_ctor(void*) { assert(false && "should not be called"); } 19 void dummy_dtor(void*) { assert(false && "should not be called"); } 20 21 void *dummy_alloc(size_t) { assert(false && "should not be called"); } 22 void dummy_dealloc(void*) { assert(false && "should not be called"); } 23 void dummy_dealloc_sized(void*, size_t) { assert(false && "should not be called"); } 24 25 26 bool check_mul_overflows(size_t x, size_t y) { 27 size_t tmp = x * y; 28 if (tmp / x != y) 29 return true; 30 return false; 31 } 32 33 bool check_add_overflows(size_t x, size_t y) { 34 size_t tmp = x + y; 35 if (tmp < x) 36 return true; 37 38 return false; 39 } 40 41 void test_overflow_in_multiplication() { 42 const size_t elem_count = std::size_t(1) << (sizeof(std::size_t) * 8 - 2); 43 const size_t elem_size = 8; 44 const size_t padding = 0; 45 assert(check_mul_overflows(elem_count, elem_size)); 46 47 try { 48 __cxxabiv1::__cxa_vec_new(elem_count, elem_size, padding, dummy_ctor, 49 dummy_dtor); 50 assert(false && "allocation should fail"); 51 } catch (std::bad_array_new_length const&) { 52 // OK 53 } catch (...) { 54 assert(false && "unexpected exception"); 55 } 56 57 try { 58 __cxxabiv1::__cxa_vec_new2(elem_count, elem_size, padding, dummy_ctor, 59 dummy_dtor, &dummy_alloc, &dummy_dealloc); 60 assert(false && "allocation should fail"); 61 } catch (std::bad_array_new_length const&) { 62 // OK 63 } catch (...) { 64 assert(false && "unexpected exception"); 65 } 66 67 try { 68 __cxxabiv1::__cxa_vec_new3(elem_count, elem_size, padding, dummy_ctor, 69 dummy_dtor, &dummy_alloc, &dummy_dealloc_sized); 70 assert(false && "allocation should fail"); 71 } catch (std::bad_array_new_length const&) { 72 // OK 73 } catch (...) { 74 assert(false && "unexpected exception"); 75 } 76 } 77 78 void test_overflow_in_addition() { 79 const size_t elem_size = 4; 80 const size_t elem_count = static_cast<size_t>(-1) / 4u; 81 #if defined(_LIBCXXABI_ARM_EHABI) 82 const size_t padding = 8; 83 #else 84 const size_t padding = sizeof(std::size_t); 85 #endif 86 assert(!check_mul_overflows(elem_count, elem_size)); 87 assert(check_add_overflows(elem_count * elem_size, padding)); 88 try { 89 __cxxabiv1::__cxa_vec_new(elem_count, elem_size, padding, dummy_ctor, 90 dummy_dtor); 91 assert(false && "allocation should fail"); 92 } catch (std::bad_array_new_length const&) { 93 // OK 94 } catch (...) { 95 assert(false && "unexpected exception"); 96 } 97 98 99 try { 100 __cxxabiv1::__cxa_vec_new2(elem_count, elem_size, padding, dummy_ctor, 101 dummy_dtor, &dummy_alloc, &dummy_dealloc); 102 assert(false && "allocation should fail"); 103 } catch (std::bad_array_new_length const&) { 104 // OK 105 } catch (...) { 106 assert(false && "unexpected exception"); 107 } 108 109 try { 110 __cxxabiv1::__cxa_vec_new3(elem_count, elem_size, padding, dummy_ctor, 111 dummy_dtor, &dummy_alloc, &dummy_dealloc_sized); 112 assert(false && "allocation should fail"); 113 } catch (std::bad_array_new_length const&) { 114 // OK 115 } catch (...) { 116 assert(false && "unexpected exception"); 117 } 118 } 119 120 int main(int, char**) { 121 test_overflow_in_multiplication(); 122 test_overflow_in_addition(); 123 124 return 0; 125 }