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