[libcxx] Fix __RAII_IncreaseAnnotator for increases >= 1

Summary: Fix suggested by @mclow.lists on D8109. Store the size of the un-poisoned vector upon construction instead of calculating it later.

Reviewers: titus, mclow.lists, kcc, EricWF

Reviewed By: EricWF

Subscribers: mclow.lists, cfe-commits

Differential Revision: http://reviews.llvm.org/D8172

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@231729 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier 2015-03-10 00:25:20 +00:00
parent 131219802f
commit 9f4f2215b7
2 changed files with 37 additions and 3 deletions

View File

@ -868,17 +868,17 @@ private:
// but if an exception is thrown after that the annotation has to be undone. // but if an exception is thrown after that the annotation has to be undone.
struct __RAII_IncreaseAnnotator { struct __RAII_IncreaseAnnotator {
__RAII_IncreaseAnnotator(const vector &__v, size_type __n = 1) __RAII_IncreaseAnnotator(const vector &__v, size_type __n = 1)
: __commit(false), __v(__v), __n(__n) { : __commit(false), __v(__v), __old_size(__v.size() + __n) {
__v.__annotate_increase(__n); __v.__annotate_increase(__n);
} }
void __done() { __commit = true; } void __done() { __commit = true; }
~__RAII_IncreaseAnnotator() { ~__RAII_IncreaseAnnotator() {
if (__commit) return; if (__commit) return;
__v.__annotate_shrink(__v.size() + __n); __v.__annotate_shrink(__old_size);
} }
bool __commit; bool __commit;
size_type __n;
const vector &__v; const vector &__v;
size_type __old_size;
}; };
#else #else
struct __RAII_IncreaseAnnotator { struct __RAII_IncreaseAnnotator {

View File

@ -37,6 +37,22 @@ private:
char a; 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() { void test_push_back() {
std::vector<X> v; std::vector<X> v;
v.reserve(2); v.reserve(2);
@ -157,6 +173,23 @@ void test_insert_n() {
assert(0); 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() { void test_resize() {
std::vector<X> v; std::vector<X> v;
v.reserve(3); v.reserve(3);
@ -193,6 +226,7 @@ int main() {
test_emplace(); test_emplace();
test_insert_range2(); test_insert_range2();
test_insert_n(); test_insert_n();
test_insert_n2();
test_resize(); test_resize();
test_resize_param(); test_resize_param();
} }