[libcxx] r242617 - Add missing instrumentation in vector::insert - Patch from Anna Zaks

Eric Fiselier eric at efcs.ca
Sat Jul 18 11:22:12 PDT 2015


Author: ericwf
Date: Sat Jul 18 13:22:12 2015
New Revision: 242617

URL: http://llvm.org/viewvc/llvm-project?rev=242617&view=rev
Log:
Add missing instrumentation in vector::insert - Patch from Anna Zaks

This patch was reviewed as D10859. http://reviews.llvm.org/D10859

Added:
    libcxx/trunk/test/libcxx/containers/sequences/
    libcxx/trunk/test/libcxx/containers/sequences/vector/
    libcxx/trunk/test/libcxx/containers/sequences/vector/asan.pass.cpp
    libcxx/trunk/test/libcxx/containers/sequences/vector/asan_throw.pass.cpp
Removed:
    libcxx/trunk/test/std/containers/sequences/vector/asan.pass.cpp
    libcxx/trunk/test/std/containers/sequences/vector/asan_throw.pass.cpp
Modified:
    libcxx/trunk/include/vector

Modified: libcxx/trunk/include/vector
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/vector?rev=242617&r1=242616&r2=242617&view=diff
==============================================================================
--- libcxx/trunk/include/vector (original)
+++ libcxx/trunk/include/vector Sat Jul 18 13:22:12 2015
@@ -1897,9 +1897,11 @@ vector<_Tp, _Allocator>::insert(const_it
     pointer __old_last = this->__end_;
     for (; this->__end_ != this->__end_cap() && __first != __last; ++__first)
     {
+        __RAII_IncreaseAnnotator __annotator(*this);
         __alloc_traits::construct(__a, _VSTD::__to_raw_pointer(this->__end_),
                                   *__first);
         ++this->__end_;
+        __annotator.__done();
     }
     __split_buffer<value_type, allocator_type&> __v(__a);
     if (__first != __last)

Added: libcxx/trunk/test/libcxx/containers/sequences/vector/asan.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/containers/sequences/vector/asan.pass.cpp?rev=242617&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/containers/sequences/vector/asan.pass.cpp (added)
+++ libcxx/trunk/test/libcxx/containers/sequences/vector/asan.pass.cpp Sat Jul 18 13:22:12 2015
@@ -0,0 +1,66 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <vector>
+
+// reference operator[](size_type n);
+
+#include <vector>
+#include <cassert>
+#include <cstdlib>
+
+#include "asan_testing.h"
+#include "min_allocator.h"
+#include "test_iterators.h"
+#include "test_macros.h"
+
+#ifndef _LIBCPP_HAS_NO_ASAN
+extern "C" void __asan_set_error_exit_code(int);
+
+
+int main()
+{
+#if TEST_STD_VER >= 11
+    {
+        typedef int T;
+        typedef std::vector<T, min_allocator<T>> C;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(std::begin(t), std::end(t));
+        c.reserve(2*c.size());
+        T foo = c[c.size()];    // bad, but not caught by ASAN
+    }
+#endif
+
+    {
+        typedef input_iterator<int*> MyInputIter;
+        // Sould not trigger ASan.
+        std::vector<int> v;
+        v.reserve(1);
+        int i[] = {42};
+        v.insert(v.begin(), MyInputIter(i), MyInputIter(i + 1));
+        assert(v[0] == 42);
+        assert(is_contiguous_container_asan_correct(v));
+    }
+
+    __asan_set_error_exit_code(0);
+    {
+        typedef int T;
+        typedef std::vector<T> C;
+        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+        C c(std::begin(t), std::end(t));
+        c.reserve(2*c.size());
+        assert(is_contiguous_container_asan_correct(c));
+        assert(!__sanitizer_verify_contiguous_container ( c.data(), c.data() + 1, c.data() + c.capacity()));
+        T foo = c[c.size()];    // should trigger ASAN
+        assert(false);          // if we got here, ASAN didn't trigger
+    }
+}
+#else
+int main () { return 0; }
+#endif

Added: libcxx/trunk/test/libcxx/containers/sequences/vector/asan_throw.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/containers/sequences/vector/asan_throw.pass.cpp?rev=242617&view=auto
==============================================================================
--- libcxx/trunk/test/libcxx/containers/sequences/vector/asan_throw.pass.cpp (added)
+++ libcxx/trunk/test/libcxx/containers/sequences/vector/asan_throw.pass.cpp Sat Jul 18 13:22:12 2015
@@ -0,0 +1,232 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// Test asan vector annotations with a class that throws in a CTOR.
+
+#include <vector>
+#include <cassert>
+
+#include "asan_testing.h"
+
+class X {
+public:
+  X(const X &x) { Init(x.a); }
+  X(char arg) { Init(arg); }
+  X() { Init(42); }
+  X &operator=(const X &x) {
+    Init(x.a);
+    return *this;
+  }
+  void Init(char arg) {
+    if (arg == 42)
+      throw 0;
+    if (arg == 66)
+      arg = 42;
+    a = arg;
+  }
+  char get() const { return a; }
+  void set(char arg) { a = arg; }
+
+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);
+  v.push_back(X(2));
+  assert(v.size() == 1);
+  try {
+    v.push_back(X(66));
+    assert(0);
+  } catch (int e) {
+    assert(v.size() == 1);
+  }
+  assert(v.size() == 1);
+  assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_emplace_back() {
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+  std::vector<X> v;
+  v.reserve(2);
+  v.push_back(X(2));
+  assert(v.size() == 1);
+  try {
+    v.emplace_back(42);
+    assert(0);
+  } catch (int e) {
+    assert(v.size() == 1);
+  }
+  assert(v.size() == 1);
+  assert(is_contiguous_container_asan_correct(v));
+#endif // _LIBCPP_HAS_NO_VARIADICS
+}
+
+void test_insert_range() {
+  std::vector<X> v;
+  v.reserve(4);
+  v.push_back(X(1));
+  v.push_back(X(2));
+  assert(v.size() == 2);
+  assert(v.capacity() >= 4);
+  try {
+    char a[2] = {21, 42};
+    v.insert(v.end(), a, a + 2);
+    assert(0);
+  } catch (int e) {
+    assert(v.size() == 3);
+  }
+  assert(v.size() == 3);
+  assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_insert() {
+  std::vector<X> v;
+  v.reserve(3);
+  v.insert(v.end(), X(1));
+  v.insert(v.begin(), X(2));
+  assert(v.size() == 2);
+  try {
+    v.insert(v.end(), X(66));
+    assert(0);
+  } catch (int e) {
+    assert(v.size() == 2);
+  }
+  assert(v.size() == 2);
+  assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_emplace() {
+#ifndef _LIBCPP_HAS_NO_VARIADICS
+  std::vector<X> v;
+  v.reserve(3);
+  v.insert(v.end(), X(1));
+  v.insert(v.begin(), X(2));
+  assert(v.size() == 2);
+  try {
+    v.emplace(v.end(), 42);
+    assert(0);
+  } catch (int e) {
+    assert(v.size() == 2);
+  }
+  assert(v.size() == 2);
+  assert(is_contiguous_container_asan_correct(v));
+#endif // _LIBCPP_HAS_NO_VARIADICS
+}
+
+void test_insert_range2() {
+  std::vector<X> v;
+  v.reserve(4);
+  v.insert(v.end(), X(1));
+  v.insert(v.begin(), X(2));
+  assert(v.size() == 2);
+  assert(v.capacity() >= 4);
+  try {
+    char a[2] = {10, 42};
+    v.insert(v.begin(), a, a + 2);
+    assert(0);
+  } catch (int e) {
+    assert(v.size() <= 4);
+    assert(is_contiguous_container_asan_correct(v));
+    return;
+  }
+  assert(0);
+}
+
+void test_insert_n() {
+  std::vector<X> v;
+  v.reserve(10);
+  v.insert(v.end(), X(1));
+  v.insert(v.begin(), X(2));
+  assert(v.size() == 2);
+  try {
+    v.insert(v.begin(), 1, X(66));
+    assert(0);
+  } catch (int e) {
+    assert(v.size() <= 3);
+    assert(is_contiguous_container_asan_correct(v));
+    return;
+  }
+  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);
+  v.push_back(X(0));
+  try {
+    v.resize(3);
+    assert(0);
+  } catch (int e) {
+    assert(v.size() == 1);
+  }
+  assert(v.size() == 1);
+  assert(is_contiguous_container_asan_correct(v));
+}
+
+void test_resize_param() {
+  std::vector<X> v;
+  v.reserve(3);
+  v.push_back(X(0));
+  try {
+    v.resize(3, X(66));
+    assert(0);
+  } catch (int e) {
+    assert(v.size() == 1);
+  }
+  assert(v.size() == 1);
+  assert(is_contiguous_container_asan_correct(v));
+}
+
+int main() {
+  test_push_back();
+  test_emplace_back();
+  test_insert_range();
+  test_insert();
+  test_emplace();
+  test_insert_range2();
+  test_insert_n();
+  test_insert_n2();
+  test_resize();
+  test_resize_param();
+}

Removed: libcxx/trunk/test/std/containers/sequences/vector/asan.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/vector/asan.pass.cpp?rev=242616&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/sequences/vector/asan.pass.cpp (original)
+++ libcxx/trunk/test/std/containers/sequences/vector/asan.pass.cpp (removed)
@@ -1,52 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// <vector>
-
-// reference operator[](size_type n);
-
-#include <vector>
-#include <cassert>
-#include <cstdlib>
-
-#include "min_allocator.h"
-#include "asan_testing.h"
-
-#ifndef _LIBCPP_HAS_NO_ASAN
-extern "C" void __asan_set_error_exit_code(int);
-
-int main()
-{
-#if __cplusplus >= 201103L
-    {
-        typedef int T;
-        typedef std::vector<T, min_allocator<T>> C;
-        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
-        C c(std::begin(t), std::end(t));
-        c.reserve(2*c.size());
-        T foo = c[c.size()];    // bad, but not caught by ASAN
-    }
-#endif
-    
-    __asan_set_error_exit_code(0);
-    {
-        typedef int T;
-        typedef std::vector<T> C;
-        const T t[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
-        C c(std::begin(t), std::end(t));
-        c.reserve(2*c.size());
-        assert(is_contiguous_container_asan_correct(c)); 
-        assert(!__sanitizer_verify_contiguous_container ( c.data(), c.data() + 1, c.data() + c.capacity()));
-        T foo = c[c.size()];    // should trigger ASAN
-        assert(false);          // if we got here, ASAN didn't trigger
-    }
-}
-#else
-int main () { return 0; }
-#endif

Removed: libcxx/trunk/test/std/containers/sequences/vector/asan_throw.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/vector/asan_throw.pass.cpp?rev=242616&view=auto
==============================================================================
--- libcxx/trunk/test/std/containers/sequences/vector/asan_throw.pass.cpp (original)
+++ libcxx/trunk/test/std/containers/sequences/vector/asan_throw.pass.cpp (removed)
@@ -1,232 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// Test asan vector annotations with a class that throws in a CTOR.
-
-#include <vector>
-#include <cassert>
-
-#include "asan_testing.h"
-
-class X {
-public:
-  X(const X &x) { Init(x.a); }
-  X(char arg) { Init(arg); }
-  X() { Init(42); }
-  X &operator=(const X &x) {
-    Init(x.a);
-    return *this;
-  }
-  void Init(char arg) {
-    if (arg == 42)
-      throw 0;
-    if (arg == 66)
-      arg = 42;
-    a = arg;
-  }
-  char get() const { return a; }
-  void set(char arg) { a = arg; }
-
-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);
-  v.push_back(X(2));
-  assert(v.size() == 1);
-  try {
-    v.push_back(X(66));
-    assert(0);
-  } catch (int e) {
-    assert(v.size() == 1);
-  }
-  assert(v.size() == 1);
-  assert(is_contiguous_container_asan_correct(v));
-}
-
-void test_emplace_back() {
-#ifndef _LIBCPP_HAS_NO_VARIADICS
-  std::vector<X> v;
-  v.reserve(2);
-  v.push_back(X(2));
-  assert(v.size() == 1);
-  try {
-    v.emplace_back(42);
-    assert(0);
-  } catch (int e) {
-    assert(v.size() == 1);
-  }
-  assert(v.size() == 1);
-  assert(is_contiguous_container_asan_correct(v));
-#endif // _LIBCPP_HAS_NO_VARIADICS
-}
-
-void test_insert_range() {
-  std::vector<X> v;
-  v.reserve(4);
-  v.push_back(X(1));
-  v.push_back(X(2));
-  assert(v.size() == 2);
-  assert(v.capacity() >= 4);
-  try {
-    char a[2] = {21, 42};
-    v.insert(v.end(), a, a + 2);
-    assert(0);
-  } catch (int e) {
-    assert(v.size() == 3);
-  }
-  assert(v.size() == 3);
-  assert(is_contiguous_container_asan_correct(v));
-}
-
-void test_insert() {
-  std::vector<X> v;
-  v.reserve(3);
-  v.insert(v.end(), X(1));
-  v.insert(v.begin(), X(2));
-  assert(v.size() == 2);
-  try {
-    v.insert(v.end(), X(66));
-    assert(0);
-  } catch (int e) {
-    assert(v.size() == 2);
-  }
-  assert(v.size() == 2);
-  assert(is_contiguous_container_asan_correct(v));
-}
-
-void test_emplace() {
-#ifndef _LIBCPP_HAS_NO_VARIADICS
-  std::vector<X> v;
-  v.reserve(3);
-  v.insert(v.end(), X(1));
-  v.insert(v.begin(), X(2));
-  assert(v.size() == 2);
-  try {
-    v.emplace(v.end(), 42);
-    assert(0);
-  } catch (int e) {
-    assert(v.size() == 2);
-  }
-  assert(v.size() == 2);
-  assert(is_contiguous_container_asan_correct(v));
-#endif // _LIBCPP_HAS_NO_VARIADICS
-}
-
-void test_insert_range2() {
-  std::vector<X> v;
-  v.reserve(4);
-  v.insert(v.end(), X(1));
-  v.insert(v.begin(), X(2));
-  assert(v.size() == 2);
-  assert(v.capacity() >= 4);
-  try {
-    char a[2] = {10, 42};
-    v.insert(v.begin(), a, a + 2);
-    assert(0);
-  } catch (int e) {
-    assert(v.size() <= 4);
-    assert(is_contiguous_container_asan_correct(v));
-    return;
-  }
-  assert(0);
-}
-
-void test_insert_n() {
-  std::vector<X> v;
-  v.reserve(10);
-  v.insert(v.end(), X(1));
-  v.insert(v.begin(), X(2));
-  assert(v.size() == 2);
-  try {
-    v.insert(v.begin(), 1, X(66));
-    assert(0);
-  } catch (int e) {
-    assert(v.size() <= 3);
-    assert(is_contiguous_container_asan_correct(v));
-    return;
-  }
-  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);
-  v.push_back(X(0));
-  try {
-    v.resize(3);
-    assert(0);
-  } catch (int e) {
-    assert(v.size() == 1);
-  }
-  assert(v.size() == 1);
-  assert(is_contiguous_container_asan_correct(v));
-}
-
-void test_resize_param() {
-  std::vector<X> v;
-  v.reserve(3);
-  v.push_back(X(0));
-  try {
-    v.resize(3, X(66));
-    assert(0);
-  } catch (int e) {
-    assert(v.size() == 1);
-  }
-  assert(v.size() == 1);
-  assert(is_contiguous_container_asan_correct(v));
-}
-
-int main() {
-  test_push_back();
-  test_emplace_back();
-  test_insert_range();
-  test_insert();
-  test_emplace();
-  test_insert_range2();
-  test_insert_n();
-  test_insert_n2();
-  test_resize();
-  test_resize_param();
-}





More information about the cfe-commits mailing list