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