Skip to content

Commit df18ba2

Browse files
authored
Stop double protecting writable vectors (#365)
* Stop double protecting writable vectors And fix memory leak when assigning a `writable::r_vector<T>&&` temporary value to an existing `writable::r_vector<T>`. * NEWS bullet * Add read only move constructor and move assignment operator * Add more assignment operator tests * Add some extra comments on read only vector from writable vector ctor * Slightly more explicit writable from read only lvalue ctor * Fix issue related to writable move constructor And add more related tests * Add extra test for capacity tracking * Add a test for the read only copy constructor from writable vectors * Tiny tweak
1 parent 6189417 commit df18ba2

File tree

12 files changed

+448
-114
lines changed

12 files changed

+448
-114
lines changed

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# cpp11 (development version)
22

3+
* Read only `r_vector`s now have a move constructor and move assignment
4+
operator (#365).
5+
6+
* Fixed an issue where writable vectors were being protected twice (#365).
7+
38
* Removed usage of the following non-API functions:
49
* `SETLENGTH()`
510
* `SET_TRUELENGTH()`

cpp11test/src/test-doubles.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,11 @@ context("doubles-C++") {
233233
w = z;
234234
expect_true(w.size() == 5);
235235
expect_true(w.data() != z.data());
236-
expect_true(w.is_altrep() == z.is_altrep());
236+
// Shallow duplication of objects of a very small size (like 1:5) don't result in
237+
// a new ALTREP object. Make sure we check ALTREP-ness of the newly duplicated object,
238+
// instead of just blindly inheriting the ALTREP-ness of the thing we duplicate.
239+
expect_true(w.is_altrep() != z.is_altrep());
240+
expect_true(w.is_altrep() == ALTREP(w.data()));
237241
}
238242

239243
test_that("writable::doubles(SEXP) move assignment") {

cpp11test/src/test-integers.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#include "cpp11/doubles.hpp"
33
#include "cpp11/function.hpp"
44
#include "cpp11/integers.hpp"
5-
#include "cpp11/protect.hpp"
65
#include "cpp11/strings.hpp"
76

87
#include <testthat.h>
@@ -208,22 +207,4 @@ context("integers-C++") {
208207
int y = NA_INTEGER;
209208
expect_true(cpp11::is_na(y));
210209
}
211-
212-
test_that("writable integer vector temporary isn't leaked (#338)") {
213-
R_xlen_t before = cpp11::detail::store::count();
214-
215-
// +1 from `x` allocation
216-
cpp11::writable::integers x(1);
217-
218-
// Calls move assignment operator `operator=(r_vector<T>&& rhs)`
219-
// +1 from `rhs` allocation and move into `x`
220-
// -1 from old `x` release
221-
x = cpp11::writable::integers(1);
222-
223-
R_xlen_t after = cpp11::detail::store::count();
224-
225-
expect_true(before == 0);
226-
// TODO: This should be 1 but writable vectors are being double protected
227-
expect_true(after - before == 2);
228-
}
229210
}

cpp11test/src/test-list.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -163,22 +163,4 @@ context("list-C++") {
163163
expect_true(Rf_xlength(y) == 0);
164164
expect_true(y != R_NilValue);
165165
}
166-
167-
test_that("writable list vector temporary isn't leaked (#338)") {
168-
R_xlen_t before = cpp11::detail::store::count();
169-
170-
// +1 from `x` allocation
171-
cpp11::writable::list x(1);
172-
173-
// Calls move assignment operator `operator=(r_vector<T>&& rhs)`
174-
// +1 from `rhs` allocation and move into `x`
175-
// -1 from old `x` release
176-
x = cpp11::writable::list(1);
177-
178-
R_xlen_t after = cpp11::detail::store::count();
179-
180-
expect_true(before == 0);
181-
// TODO: This should be 1 but writable vectors are being double protected
182-
expect_true(after - before == 2);
183-
}
184166
}

0 commit comments

Comments
 (0)