Home | History | Annotate | Download | only in vector
      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 // Test asan vector annotations with a class that throws in a CTOR.
     12 
     13 #include <vector>
     14 #include <cassert>
     15 
     16 #include "asan_testing.h"
     17 
     18 class X {
     19 public:
     20   X(const X &x) { Init(x.a); }
     21   X(char arg) { Init(arg); }
     22   X() { Init(42); }
     23   X &operator=(const X &x) {
     24     Init(x.a);
     25     return *this;
     26   }
     27   void Init(char arg) {
     28     if (arg == 42)
     29       throw 0;
     30     if (arg == 66)
     31       arg = 42;
     32     a = arg;
     33   }
     34   char get() const { return a; }
     35   void set(char arg) { a = arg; }
     36 
     37 private:
     38   char a;
     39 };
     40 
     41 class ThrowOnCopy {
     42 public:
     43     ThrowOnCopy() : should_throw(false) {}
     44     explicit ThrowOnCopy(bool should_throw) : should_throw(should_throw) {}
     45 
     46     ThrowOnCopy(ThrowOnCopy const & other)
     47         : should_throw(other.should_throw)
     48     {
     49         if (should_throw) {
     50             throw 0;
     51         }
     52     }
     53 
     54     bool should_throw;
     55 };
     56 
     57 void test_push_back() {
     58   std::vector<X> v;
     59   v.reserve(2);
     60   v.push_back(X(2));
     61   assert(v.size() == 1);
     62   try {
     63     v.push_back(X(66));
     64     assert(0);
     65   } catch (int e) {
     66     assert(v.size() == 1);
     67   }
     68   assert(v.size() == 1);
     69   assert(is_contiguous_container_asan_correct(v));
     70 }
     71 
     72 void test_emplace_back() {
     73 #ifndef _LIBCPP_HAS_NO_VARIADICS
     74   std::vector<X> v;
     75   v.reserve(2);
     76   v.push_back(X(2));
     77   assert(v.size() == 1);
     78   try {
     79     v.emplace_back(42);
     80     assert(0);
     81   } catch (int e) {
     82     assert(v.size() == 1);
     83   }
     84   assert(v.size() == 1);
     85   assert(is_contiguous_container_asan_correct(v));
     86 #endif // _LIBCPP_HAS_NO_VARIADICS
     87 }
     88 
     89 void test_insert_range() {
     90   std::vector<X> v;
     91   v.reserve(4);
     92   v.push_back(X(1));
     93   v.push_back(X(2));
     94   assert(v.size() == 2);
     95   assert(v.capacity() >= 4);
     96   try {
     97     char a[2] = {21, 42};
     98     v.insert(v.end(), a, a + 2);
     99     assert(0);
    100   } catch (int e) {
    101     assert(v.size() == 3);
    102   }
    103   assert(v.size() == 3);
    104   assert(is_contiguous_container_asan_correct(v));
    105 }
    106 
    107 void test_insert() {
    108   std::vector<X> v;
    109   v.reserve(3);
    110   v.insert(v.end(), X(1));
    111   v.insert(v.begin(), X(2));
    112   assert(v.size() == 2);
    113   try {
    114     v.insert(v.end(), X(66));
    115     assert(0);
    116   } catch (int e) {
    117     assert(v.size() == 2);
    118   }
    119   assert(v.size() == 2);
    120   assert(is_contiguous_container_asan_correct(v));
    121 }
    122 
    123 void test_emplace() {
    124 #ifndef _LIBCPP_HAS_NO_VARIADICS
    125   std::vector<X> v;
    126   v.reserve(3);
    127   v.insert(v.end(), X(1));
    128   v.insert(v.begin(), X(2));
    129   assert(v.size() == 2);
    130   try {
    131     v.emplace(v.end(), 42);
    132     assert(0);
    133   } catch (int e) {
    134     assert(v.size() == 2);
    135   }
    136   assert(v.size() == 2);
    137   assert(is_contiguous_container_asan_correct(v));
    138 #endif // _LIBCPP_HAS_NO_VARIADICS
    139 }
    140 
    141 void test_insert_range2() {
    142   std::vector<X> v;
    143   v.reserve(4);
    144   v.insert(v.end(), X(1));
    145   v.insert(v.begin(), X(2));
    146   assert(v.size() == 2);
    147   assert(v.capacity() >= 4);
    148   try {
    149     char a[2] = {10, 42};
    150     v.insert(v.begin(), a, a + 2);
    151     assert(0);
    152   } catch (int e) {
    153     assert(v.size() <= 4);
    154     assert(is_contiguous_container_asan_correct(v));
    155     return;
    156   }
    157   assert(0);
    158 }
    159 
    160 void test_insert_n() {
    161   std::vector<X> v;
    162   v.reserve(10);
    163   v.insert(v.end(), X(1));
    164   v.insert(v.begin(), X(2));
    165   assert(v.size() == 2);
    166   try {
    167     v.insert(v.begin(), 1, X(66));
    168     assert(0);
    169   } catch (int e) {
    170     assert(v.size() <= 3);
    171     assert(is_contiguous_container_asan_correct(v));
    172     return;
    173   }
    174   assert(0);
    175 }
    176 
    177 
    178 void test_insert_n2() {
    179   std::vector<ThrowOnCopy> v(10);
    180   v.reserve(100);
    181   assert(v.size() == 10);
    182   v[6].should_throw = true;
    183   try {
    184     v.insert(v.cbegin(), 5, ThrowOnCopy());
    185     assert(0);
    186   } catch (int e) {
    187     assert(v.size() == 11);
    188     assert(is_contiguous_container_asan_correct(v));
    189     return;
    190   }
    191   assert(0);
    192 }
    193 
    194 void test_resize() {
    195   std::vector<X> v;
    196   v.reserve(3);
    197   v.push_back(X(0));
    198   try {
    199     v.resize(3);
    200     assert(0);
    201   } catch (int e) {
    202     assert(v.size() == 1);
    203   }
    204   assert(v.size() == 1);
    205   assert(is_contiguous_container_asan_correct(v));
    206 }
    207 
    208 void test_resize_param() {
    209   std::vector<X> v;
    210   v.reserve(3);
    211   v.push_back(X(0));
    212   try {
    213     v.resize(3, X(66));
    214     assert(0);
    215   } catch (int e) {
    216     assert(v.size() == 1);
    217   }
    218   assert(v.size() == 1);
    219   assert(is_contiguous_container_asan_correct(v));
    220 }
    221 
    222 int main() {
    223   test_push_back();
    224   test_emplace_back();
    225   test_insert_range();
    226   test_insert();
    227   test_emplace();
    228   test_insert_range2();
    229   test_insert_n();
    230   test_insert_n2();
    231   test_resize();
    232   test_resize_param();
    233 }
    234