127 lines · 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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: no-exceptions10 11// This test requires the fix in http://llvm.org/PR41395 (c4225e124f9e).12// XFAIL: using-built-library-before-llvm-913 14#include "cxxabi.h"15#include <cassert>16#include <cstddef>17#include <new>18 19void dummy_ctor(void*) { assert(false && "should not be called"); }20void dummy_dtor(void*) { assert(false && "should not be called"); }21 22void *dummy_alloc(size_t) { assert(false && "should not be called"); return nullptr; }23void dummy_dealloc(void*) { assert(false && "should not be called"); }24void dummy_dealloc_sized(void*, size_t) { assert(false && "should not be called"); }25 26 27bool 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 34bool 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 42void 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 // OK54 } 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 // OK64 } 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 // OK74 } catch (...) {75 assert(false && "unexpected exception");76 }77}78 79void 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#else85 const size_t padding = sizeof(std::size_t);86#endif87 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 // OK95 } 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 // OK106 } 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 // OK116 } catch (...) {117 assert(false && "unexpected exception");118 }119}120 121int main(int, char**) {122 test_overflow_in_multiplication();123 test_overflow_in_addition();124 125 return 0;126}127