[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