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