[libcxx] Fix __RAII_IncreaseAnnotator for increases >= 1
authorEric Fiselier <eric@efcs.ca>
Tue, 10 Mar 2015 00:25:20 +0000 (00:25 +0000)
committerEric Fiselier <eric@efcs.ca>
Tue, 10 Mar 2015 00:25:20 +0000 (00:25 +0000)
Summary: Fix suggested by @mclow.lists on D8109. Store the size of the un-poisoned vector upon construction instead of calculating it later.

Reviewers: titus, mclow.lists, kcc, EricWF

Reviewed By: EricWF

Subscribers: mclow.lists, cfe-commits

Differential Revision: http://reviews.llvm.org/D8172

llvm-svn: 231729

libcxx/include/vector
libcxx/test/std/containers/sequences/vector/asan_throw.pass.cpp

index 22a6343..d23164b 100644 (file)
@@ -868,17 +868,17 @@ private:
     // but if an exception is thrown after that the annotation has to be undone.
     struct __RAII_IncreaseAnnotator {
       __RAII_IncreaseAnnotator(const vector &__v, size_type __n = 1)
-        : __commit(false), __v(__v), __n(__n) {
+        : __commit(false), __v(__v), __old_size(__v.size() + __n) {
         __v.__annotate_increase(__n);
       }
       void __done() { __commit = true; }
       ~__RAII_IncreaseAnnotator() {
         if (__commit) return;
-        __v.__annotate_shrink(__v.size() + __n);
+        __v.__annotate_shrink(__old_size);
       }
       bool __commit;
-      size_type __n;
       const vector &__v;
+      size_type __old_size;
     };
 #else
     struct __RAII_IncreaseAnnotator {
index a1dce4a..c100da1 100644 (file)
@@ -37,6 +37,22 @@ private:
   char a;
 };
 
+class ThrowOnCopy {
+public:
+    ThrowOnCopy() : should_throw(false) {}
+    explicit ThrowOnCopy(bool should_throw) : should_throw(should_throw) {}
+
+    ThrowOnCopy(ThrowOnCopy const & other)
+        : should_throw(other.should_throw)
+    {
+        if (should_throw) {
+            throw 0;
+        }
+    }
+
+    bool should_throw;
+};
+
 void test_push_back() {
   std::vector<X> v;
   v.reserve(2);
@@ -157,6 +173,23 @@ void test_insert_n() {
   assert(0);
 }
 
+
+void test_insert_n2() {
+  std::vector<ThrowOnCopy> v(10);
+  v.reserve(100);
+  assert(v.size() == 10);
+  v[6].should_throw = true;
+  try {
+    v.insert(v.cbegin(), 5, ThrowOnCopy());
+    assert(0);
+  } catch (int e) {
+    assert(v.size() == 11);
+    assert(is_contiguous_container_asan_correct(v));
+    return;
+  }
+  assert(0);
+}
+
 void test_resize() {
   std::vector<X> v;
   v.reserve(3);
@@ -193,6 +226,7 @@ int main() {
   test_emplace();
   test_insert_range2();
   test_insert_n();
+  test_insert_n2();
   test_resize();
   test_resize_param();
 }