[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 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@216995 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
198
test/containers/sequences/vector/asan_throw.pass.cc
Normal file
198
test/containers/sequences/vector/asan_throw.pass.cc
Normal file
@@ -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();
|
||||
}
|
@@ -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
|
||||
#endif // ASAN_TESTING_H
|
||||
|
Reference in New Issue
Block a user