150
|
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
|
173
|
9 // UNSUPPORTED: no-exceptions
|
150
|
10
|
|
11 #include "cxxabi.h"
|
|
12 #include <new>
|
|
13 #include <cassert>
|
|
14
|
|
15 void dummy_ctor(void*) { assert(false && "should not be called"); }
|
|
16 void dummy_dtor(void*) { assert(false && "should not be called"); }
|
|
17
|
|
18 void *dummy_alloc(size_t) { assert(false && "should not be called"); }
|
|
19 void dummy_dealloc(void*) { assert(false && "should not be called"); }
|
|
20 void dummy_dealloc_sized(void*, size_t) { assert(false && "should not be called"); }
|
|
21
|
|
22
|
|
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
|
|
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
|
|
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
|
|
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
|
|
117 int main(int, char**) {
|
|
118 test_overflow_in_multiplication();
|
|
119 test_overflow_in_addition();
|
|
120
|
|
121 return 0;
|
|
122 }
|