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(); -} _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits