diff options
| author | Kostya Serebryany <kcc@google.com> | 2014-09-02 23:43:38 +0000 |
|---|---|---|
| committer | Kostya Serebryany <kcc@google.com> | 2014-09-02 23:43:38 +0000 |
| commit | 3f0e834842b1423769e0b32fc4ad595a8cb3cc30 (patch) | |
| tree | 1cdd0c8dacac7ab9f508fcdccaa726ce05baa9d8 /libcxx/test | |
| parent | ca616acd730b6e3425fa5a5ed49ade83d0e726ed (diff) | |
| download | bcm5719-llvm-3f0e834842b1423769e0b32fc4ad595a8cb3cc30.tar.gz bcm5719-llvm-3f0e834842b1423769e0b32fc4ad595a8cb3cc30.zip | |
[asan] Make vector asan annotations exception-friendly
Fix vector asan annotations with RAII.
Add a test.
Also, remove one dead function.
Review: http://reviews.llvm.org/D4170
llvm-svn: 216995
Diffstat (limited to 'libcxx/test')
| -rw-r--r-- | libcxx/test/containers/sequences/vector/asan_throw.pass.cc | 198 | ||||
| -rw-r--r-- | libcxx/test/support/asan_testing.h | 4 |
2 files changed, 200 insertions, 2 deletions
diff --git a/libcxx/test/containers/sequences/vector/asan_throw.pass.cc b/libcxx/test/containers/sequences/vector/asan_throw.pass.cc new file mode 100644 index 00000000000..a1dce4a3b44 --- /dev/null +++ b/libcxx/test/containers/sequences/vector/asan_throw.pass.cc @@ -0,0 +1,198 @@ +//===----------------------------------------------------------------------===// +// +// 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; +}; + +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_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_resize(); + test_resize_param(); +} diff --git a/libcxx/test/support/asan_testing.h b/libcxx/test/support/asan_testing.h index c8797bde6f2..45ad04b1bb2 100644 --- a/libcxx/test/support/asan_testing.h +++ b/libcxx/test/support/asan_testing.h @@ -19,7 +19,7 @@ extern "C" int __sanitizer_verify_contiguous_container template <typename T, typename Alloc> bool is_contiguous_container_asan_correct ( const std::vector<T, Alloc> &c ) { - if ( std::is_same<Alloc, std::allocator<T>>::value && c.data() != NULL) + if ( std::is_same<Alloc, std::allocator<T> >::value && c.data() != NULL) return __sanitizer_verify_contiguous_container ( c.data(), c.data() + c.size(), c.data() + c.capacity()) != 0; return true; @@ -34,4 +34,4 @@ bool is_contiguous_container_asan_correct ( const std::vector<T, Alloc> &c ) #endif -#endif // ASAN_TESTING_H
\ No newline at end of file +#endif // ASAN_TESTING_H |

