brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 679eec2 Raw
169 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: no-exceptions10 11// (bug report: https://llvm.org/PR58392)12// Check that vector constructors don't leak memory when an operation inside the constructor throws an exception13 14#include <cstddef>15#include <memory>16#include <type_traits>17#include <vector>18 19#include "../common.h"20#include "count_new.h"21#include "test_allocator.h"22#include "test_iterators.h"23 24int main(int, char**) {25  using AllocVec = std::vector<int, throwing_allocator<int> >;26  try { // vector()27    AllocVec vec;28  } catch (int) {29  }30  check_new_delete_called();31 32  try { // Throw in vector(size_type) from type33    std::vector<throwing_t> get_alloc(1);34  } catch (int) {35  }36  check_new_delete_called();37 38#if TEST_STD_VER >= 1439  try { // Throw in vector(size_type, value_type) from type40    int throw_after = 1;41    throwing_t v(throw_after);42    std::vector<throwing_t> get_alloc(1, v);43  } catch (int) {44  }45  check_new_delete_called();46 47  try { // Throw in vector(size_type, const allocator_type&) from allocator48    throwing_allocator<int> alloc(/*throw_on_ctor = */ false, /*throw_on_copy = */ true);49    AllocVec get_alloc(0, alloc);50  } catch (int) {51  }52  check_new_delete_called();53 54  try { // Throw in vector(size_type, const allocator_type&) from the type55    std::vector<throwing_t> vec(1, std::allocator<throwing_t>());56  } catch (int) {57  }58  check_new_delete_called();59#endif // TEST_STD_VER >= 1460 61  try { // Throw in vector(size_type, value_type, const allocator_type&) from the type62    int throw_after = 1;63    throwing_t v(throw_after);64    std::vector<throwing_t> vec(1, v, std::allocator<throwing_t>());65  } catch (int) {66  }67  check_new_delete_called();68 69  try { // Throw in vector(InputIterator, InputIterator) from input iterator70    std::vector<int> vec(71        (throwing_iterator<int, std::input_iterator_tag>()), throwing_iterator<int, std::input_iterator_tag>(2));72  } catch (int) {73  }74  check_new_delete_called();75 76  try { // Throw in vector(InputIterator, InputIterator) from forward iterator77    std::vector<int> vec(78        (throwing_iterator<int, std::forward_iterator_tag>()), throwing_iterator<int, std::forward_iterator_tag>(2));79  } catch (int) {80  }81  check_new_delete_called();82 83  try { // Throw in vector(InputIterator, InputIterator) from allocator84    int a[] = {1, 2};85    AllocVec vec(cpp17_input_iterator<int*>(a), cpp17_input_iterator<int*>(a + 2));86  } catch (int) {87  }88  check_new_delete_called();89 90  try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from input iterator91    std::allocator<int> alloc;92    std::vector<int> vec(93        throwing_iterator<int, std::input_iterator_tag>(), throwing_iterator<int, std::input_iterator_tag>(2), alloc);94  } catch (int) {95  }96  check_new_delete_called();97 98  try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from forward iterator99    std::allocator<int> alloc;100    std::vector<int> vec(throwing_iterator<int, std::forward_iterator_tag>(),101                         throwing_iterator<int, std::forward_iterator_tag>(2),102                         alloc);103  } catch (int) {104  }105  check_new_delete_called();106 107  try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from allocator108    int a[] = {1, 2};109    throwing_allocator<int> alloc(/*throw_on_ctor = */ false, /*throw_on_copy = */ true);110    AllocVec vec(cpp17_input_iterator<int*>(a), cpp17_input_iterator<int*>(a + 2), alloc);111  } catch (int) {112  }113  check_new_delete_called();114 115  try { // Throw in vector(InputIterator, InputIterator, const allocator_type&) from allocator116    int a[] = {1, 2};117    throwing_allocator<int> alloc(/*throw_on_ctor = */ false, /*throw_on_copy = */ true);118    AllocVec vec(forward_iterator<int*>(a), forward_iterator<int*>(a + 2), alloc);119  } catch (int) {120  }121  check_new_delete_called();122 123  try { // Throw in vector(const vector&) from type124    std::vector<throwing_t> vec;125    int throw_after = 1;126    vec.emplace_back(throw_after);127    auto vec2 = vec;128  } catch (int) {129  }130  check_new_delete_called();131 132  try { // Throw in vector(const vector&, const allocator_type&) from type133    std::vector<throwing_t> vec;134    int throw_after = 1;135    vec.emplace_back(throw_after);136    std::vector<throwing_t> vec2(vec, std::allocator<int>());137  } catch (int) {138  }139  check_new_delete_called();140 141  try { // Throw in vector(vector&&, const allocator_type&) from type during element-wise move142    std::vector<throwing_t, test_allocator<throwing_t> > vec(test_allocator<throwing_t>(1));143    int throw_after = 10;144    throwing_t v(throw_after);145    vec.insert(vec.end(), 6, v);146    std::vector<throwing_t, test_allocator<throwing_t> > vec2(std::move(vec), test_allocator<throwing_t>(2));147  } catch (int) {148  }149  check_new_delete_called();150 151#if TEST_STD_VER >= 11152  try { // Throw in vector(initializer_list<value_type>) from type153    int throw_after = 1;154    std::vector<throwing_t> vec({throwing_t(throw_after)});155  } catch (int) {156  }157  check_new_delete_called();158 159  try { // Throw in vector(initializer_list<value_type>, const allocator_type&) constructor from type160    int throw_after = 1;161    std::vector<throwing_t> vec({throwing_t(throw_after)}, std::allocator<throwing_t>());162  } catch (int) {163  }164  check_new_delete_called();165#endif // TEST_STD_VER >= 11166 167  return 0;168}169