Home | History | Annotate | Download | only in vector.modifiers
      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