1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // XFAIL: libcpp-no-exceptions 11 // <vector> 12 13 // void push_back(const value_type& x); 14 15 #include <vector> 16 #include <cassert> 17 18 #include "asan_testing.h" 19 20 // Flag that makes the copy constructor for CMyClass throw an exception 21 static bool gCopyConstructorShouldThow = false; 22 23 24 class CMyClass { 25 public: CMyClass(int tag); 26 public: CMyClass(const CMyClass& iOther); 27 public: ~CMyClass(); 28 29 bool equal(const CMyClass &rhs) const 30 { return fTag == rhs.fTag && fMagicValue == rhs.fMagicValue; } 31 private: 32 int fMagicValue; 33 int fTag; 34 35 private: static int kStartedConstructionMagicValue; 36 private: static int kFinishedConstructionMagicValue; 37 }; 38 39 // Value for fMagicValue when the constructor has started running, but not yet finished 40 int CMyClass::kStartedConstructionMagicValue = 0; 41 // Value for fMagicValue when the constructor has finished running 42 int CMyClass::kFinishedConstructionMagicValue = 12345; 43 44 CMyClass::CMyClass(int tag) : 45 fMagicValue(kStartedConstructionMagicValue), fTag(tag) 46 { 47 // Signal that the constructor has finished running 48 fMagicValue = kFinishedConstructionMagicValue; 49 } 50 51 CMyClass::CMyClass(const CMyClass& iOther) : 52 fMagicValue(kStartedConstructionMagicValue), fTag(iOther.fTag) 53 { 54 // If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue 55 if (gCopyConstructorShouldThow) { 56 throw std::exception(); 57 } 58 // Signal that the constructor has finished running 59 fMagicValue = kFinishedConstructionMagicValue; 60 } 61 62 CMyClass::~CMyClass() { 63 // Only instances for which the constructor has finished running should be destructed 64 assert(fMagicValue == kFinishedConstructionMagicValue); 65 } 66 67 bool operator==(const CMyClass &lhs, const CMyClass &rhs) { return lhs.equal(rhs); } 68 69 int main() 70 { 71 CMyClass instance(42); 72 std::vector<CMyClass> vec; 73 74 vec.push_back(instance); 75 std::vector<CMyClass> vec2(vec); 76 assert(is_contiguous_container_asan_correct(vec)); 77 assert(is_contiguous_container_asan_correct(vec2)); 78 79 gCopyConstructorShouldThow = true; 80 try { 81 vec.push_back(instance); 82 } 83 catch (...) { 84 assert(vec==vec2); 85 assert(is_contiguous_container_asan_correct(vec)); 86 } 87 } 88