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// <vector>
10
11// void push_back(const value_type& x);
12
13#include <vector>
14#include <cassert>
15
16#include "asan_testing.h"
17#include "test_macros.h"
18
19// Flag that makes the copy constructor for CMyClass throw an exception
20static bool gCopyConstructorShouldThrow = false;
21
22class CMyClass {
23public:
24 CMyClass(int tag);
25
26public:
27 CMyClass(const CMyClass& iOther);
28
29public:
30 ~CMyClass();
31
32 bool equal(const CMyClass& rhs) const { return fTag == rhs.fTag && fMagicValue == rhs.fMagicValue; }
33
34private:
35 int fMagicValue;
36 int fTag;
37
38private:
39 static int kStartedConstructionMagicValue;
40
41private:
42 static int kFinishedConstructionMagicValue;
43};
44
45// Value for fMagicValue when the constructor has started running, but not yet finished
46int CMyClass::kStartedConstructionMagicValue = 0;
47// Value for fMagicValue when the constructor has finished running
48int CMyClass::kFinishedConstructionMagicValue = 12345;
49
50CMyClass::CMyClass(int tag) : fMagicValue(kStartedConstructionMagicValue), fTag(tag) {
51 // Signal that the constructor has finished running
52 fMagicValue = kFinishedConstructionMagicValue;
53}
54
55CMyClass::CMyClass(const CMyClass& iOther) : fMagicValue(kStartedConstructionMagicValue), fTag(iOther.fTag) {
56 // If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue
57 if (gCopyConstructorShouldThrow) {
58 TEST_THROW(std::exception());
59 }
60 // Signal that the constructor has finished running
61 fMagicValue = kFinishedConstructionMagicValue;
62}
63
64CMyClass::~CMyClass() {
65 // Only instances for which the constructor has finished running should be destructed
66 assert(fMagicValue == kFinishedConstructionMagicValue);
67}
68
69bool operator==(const CMyClass& lhs, const CMyClass& rhs) { return lhs.equal(rhs); }
70
71int main(int, char**) {
72 CMyClass instance(42);
73 std::vector<CMyClass> vec;
74
75 vec.push_back(x: instance);
76 std::vector<CMyClass> vec2(vec);
77 assert(is_contiguous_container_asan_correct(vec));
78 assert(is_contiguous_container_asan_correct(vec2));
79
80#ifndef TEST_HAS_NO_EXCEPTIONS
81 gCopyConstructorShouldThrow = true;
82 try {
83 vec.push_back(x: instance);
84 assert(false);
85 } catch (...) {
86 assert(vec == vec2);
87 assert(is_contiguous_container_asan_correct(vec));
88 }
89#endif
90
91 return 0;
92}
93

source code of libcxx/test/std/containers/sequences/vector/vector.modifiers/push_back_exception_safety.pass.cpp