//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // UNSUPPORTED: no-exceptions #include "cxxabi.h" #include #include void dummy_ctor(void*) { assert(false && "should not be called"); } void dummy_dtor(void*) { assert(false && "should not be called"); } void *dummy_alloc(size_t) { assert(false && "should not be called"); } void dummy_dealloc(void*) { assert(false && "should not be called"); } void dummy_dealloc_sized(void*, size_t) { assert(false && "should not be called"); } bool check_mul_overflows(size_t x, size_t y) { size_t tmp = x * y; if (tmp / x != y) return true; return false; } bool check_add_overflows(size_t x, size_t y) { size_t tmp = x + y; if (tmp < x) return true; return false; } void test_overflow_in_multiplication() { const size_t elem_count = std::size_t(1) << (sizeof(std::size_t) * 8 - 2); const size_t elem_size = 8; const size_t padding = 0; assert(check_mul_overflows(elem_count, elem_size)); try { __cxxabiv1::__cxa_vec_new(elem_count, elem_size, padding, dummy_ctor, dummy_dtor); assert(false && "allocation should fail"); } catch (std::bad_array_new_length const&) { // OK } catch (...) { assert(false && "unexpected exception"); } try { __cxxabiv1::__cxa_vec_new2(elem_count, elem_size, padding, dummy_ctor, dummy_dtor, &dummy_alloc, &dummy_dealloc); assert(false && "allocation should fail"); } catch (std::bad_array_new_length const&) { // OK } catch (...) { assert(false && "unexpected exception"); } try { __cxxabiv1::__cxa_vec_new3(elem_count, elem_size, padding, dummy_ctor, dummy_dtor, &dummy_alloc, &dummy_dealloc_sized); assert(false && "allocation should fail"); } catch (std::bad_array_new_length const&) { // OK } catch (...) { assert(false && "unexpected exception"); } } void test_overflow_in_addition() { const size_t elem_size = 4; const size_t elem_count = static_cast(-1) / 4u; #if defined(_LIBCXXABI_ARM_EHABI) const size_t padding = 8; #else const size_t padding = sizeof(std::size_t); #endif assert(!check_mul_overflows(elem_count, elem_size)); assert(check_add_overflows(elem_count * elem_size, padding)); try { __cxxabiv1::__cxa_vec_new(elem_count, elem_size, padding, dummy_ctor, dummy_dtor); assert(false && "allocation should fail"); } catch (std::bad_array_new_length const&) { // OK } catch (...) { assert(false && "unexpected exception"); } try { __cxxabiv1::__cxa_vec_new2(elem_count, elem_size, padding, dummy_ctor, dummy_dtor, &dummy_alloc, &dummy_dealloc); assert(false && "allocation should fail"); } catch (std::bad_array_new_length const&) { // OK } catch (...) { assert(false && "unexpected exception"); } try { __cxxabiv1::__cxa_vec_new3(elem_count, elem_size, padding, dummy_ctor, dummy_dtor, &dummy_alloc, &dummy_dealloc_sized); assert(false && "allocation should fail"); } catch (std::bad_array_new_length const&) { // OK } catch (...) { assert(false && "unexpected exception"); } } int main(int, char**) { test_overflow_in_multiplication(); test_overflow_in_addition(); return 0; }