/ test / cxa_vec_new_overflow_PR41395.pass.cpp
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  }