[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:
parent
131219802f
commit
9f4f2215b7
@ -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 {
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user