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