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