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