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 // This test requires the fix in http://llvm.org/PR41395 (c4225e124f9e). 12 // XFAIL: using-built-library-before-llvm-9 13 14 #include "cxxabi.h" 15 #include <cassert> 16 #include <cstddef> 17 #include <new> 18 19 void dummy_ctor(void*) { assert(false && "should not be called"); } 20 void dummy_dtor(void*) { assert(false && "should not be called"); } 21 22 void *dummy_alloc(size_t) { assert(false && "should not be called"); return nullptr; } 23 void dummy_dealloc(void*) { assert(false && "should not be called"); } 24 void dummy_dealloc_sized(void*, size_t) { assert(false && "should not be called"); } 25 26 27 bool check_mul_overflows(size_t x, size_t y) { 28 size_t tmp = x * y; 29 if (tmp / x != y) 30 return true; 31 return false; 32 } 33 34 bool check_add_overflows(size_t x, size_t y) { 35 size_t tmp = x + y; 36 if (tmp < x) 37 return true; 38 39 return false; 40 } 41 42 void test_overflow_in_multiplication() { 43 const size_t elem_count = std::size_t(1) << (sizeof(std::size_t) * 8 - 2); 44 const size_t elem_size = 8; 45 const size_t padding = 0; 46 assert(check_mul_overflows(elem_count, elem_size)); 47 48 try { 49 __cxxabiv1::__cxa_vec_new(elem_count, elem_size, padding, dummy_ctor, 50 dummy_dtor); 51 assert(false && "allocation should fail"); 52 } catch (std::bad_array_new_length const&) { 53 // OK 54 } catch (...) { 55 assert(false && "unexpected exception"); 56 } 57 58 try { 59 __cxxabiv1::__cxa_vec_new2(elem_count, elem_size, padding, dummy_ctor, 60 dummy_dtor, &dummy_alloc, &dummy_dealloc); 61 assert(false && "allocation should fail"); 62 } catch (std::bad_array_new_length const&) { 63 // OK 64 } catch (...) { 65 assert(false && "unexpected exception"); 66 } 67 68 try { 69 __cxxabiv1::__cxa_vec_new3(elem_count, elem_size, padding, dummy_ctor, 70 dummy_dtor, &dummy_alloc, &dummy_dealloc_sized); 71 assert(false && "allocation should fail"); 72 } catch (std::bad_array_new_length const&) { 73 // OK 74 } catch (...) { 75 assert(false && "unexpected exception"); 76 } 77 } 78 79 void test_overflow_in_addition() { 80 const size_t elem_size = 4; 81 const size_t elem_count = static_cast<size_t>(-1) / 4u; 82 #if defined(_LIBCXXABI_ARM_EHABI) 83 const size_t padding = 8; 84 #else 85 const size_t padding = sizeof(std::size_t); 86 #endif 87 assert(!check_mul_overflows(elem_count, elem_size)); 88 assert(check_add_overflows(elem_count * elem_size, padding)); 89 try { 90 __cxxabiv1::__cxa_vec_new(elem_count, elem_size, padding, dummy_ctor, 91 dummy_dtor); 92 assert(false && "allocation should fail"); 93 } catch (std::bad_array_new_length const&) { 94 // OK 95 } catch (...) { 96 assert(false && "unexpected exception"); 97 } 98 99 100 try { 101 __cxxabiv1::__cxa_vec_new2(elem_count, elem_size, padding, dummy_ctor, 102 dummy_dtor, &dummy_alloc, &dummy_dealloc); 103 assert(false && "allocation should fail"); 104 } catch (std::bad_array_new_length const&) { 105 // OK 106 } catch (...) { 107 assert(false && "unexpected exception"); 108 } 109 110 try { 111 __cxxabiv1::__cxa_vec_new3(elem_count, elem_size, padding, dummy_ctor, 112 dummy_dtor, &dummy_alloc, &dummy_dealloc_sized); 113 assert(false && "allocation should fail"); 114 } catch (std::bad_array_new_length const&) { 115 // OK 116 } catch (...) { 117 assert(false && "unexpected exception"); 118 } 119 } 120 121 int main(int, char**) { 122 test_overflow_in_multiplication(); 123 test_overflow_in_addition(); 124 125 return 0; 126 } 127