Skip to content

Commit 4813640

Browse files
authored
Merge pull request #893 from krlmlr/f-no-init-protect
Rewrite no_init() and other functions to reduce false positives
2 parents 522e66d + b735942 commit 4813640

File tree

5 files changed

+21
-7
lines changed

5 files changed

+21
-7
lines changed

inst/include/Rcpp/api/meat/Rcpp_eval.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ inline SEXP Rcpp_fast_eval(SEXP expr, SEXP env) {
7575
inline SEXP Rcpp_eval(SEXP expr, SEXP env) {
7676

7777
// 'identity' function used to capture errors, interrupts
78-
SEXP identity = Rf_findFun(::Rf_install("identity"), R_BaseNamespace);
78+
Shield<SEXP> identity(Rf_findFun(::Rf_install("identity"), R_BaseNamespace));
7979

8080
if (identity == R_UnboundValue) {
8181
stop("Failed to find 'base::identity()'");

inst/include/Rcpp/exceptions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ namespace internal {
243243
inline bool is_Rcpp_eval_call(SEXP expr) {
244244
SEXP sys_calls_symbol = Rf_install("sys.calls");
245245
SEXP identity_symbol = Rf_install("identity");
246-
SEXP identity_fun = Rf_findFun(identity_symbol, R_BaseEnv);
246+
Shield<SEXP> identity_fun(Rf_findFun(identity_symbol, R_BaseEnv));
247247
SEXP tryCatch_symbol = Rf_install("tryCatch");
248248
SEXP evalq_symbol = Rf_install("evalq");
249249

inst/include/Rcpp/protection/Shelter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ namespace Rcpp {
2727

2828
inline SEXP operator()(SEXP x){
2929
nprotected++;
30-
return PROTECT(x) ;
30+
return Rcpp_protect(x) ;
3131
}
3232

3333
~Shelter(){
34-
UNPROTECT(nprotected) ;
34+
Rcpp_unprotect(nprotected) ;
3535
nprotected = 0 ;
3636
}
3737

inst/include/Rcpp/protection/Shield.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,18 @@ namespace Rcpp{
2525
return x ;
2626
}
2727

28+
inline void Rcpp_unprotect(int i){
29+
// Prefer this function over UNPROTECT() in Rcpp so that all
30+
// balance checks errors by rchk are contained at one location (#892)
31+
UNPROTECT(i);
32+
}
33+
2834
template <typename T>
2935
class Shield{
3036
public:
3137
Shield( SEXP t_) : t(Rcpp_protect(t_)){}
3238
~Shield(){
33-
if( t != R_NilValue ) UNPROTECT(1) ;
39+
if( t != R_NilValue ) Rcpp_unprotect(1) ;
3440
}
3541

3642
operator SEXP() const { return t; }

inst/include/Rcpp/vector/no_init.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ class no_init_vector {
3737

3838
template <int RTYPE, template <class> class StoragePolicy >
3939
operator Vector<RTYPE, StoragePolicy>() const {
40-
return Rf_allocVector(RTYPE, size) ;
40+
// Explicitly protect temporary vector to avoid false positive
41+
// with rchk (#892)
42+
Shield<SEXP> x(Rf_allocVector(RTYPE, size));
43+
Vector<RTYPE, PreserveStorage> ret(x);
44+
return ret;
4145
}
4246

4347
private:
@@ -58,7 +62,11 @@ class no_init_matrix {
5862

5963
template <int RTYPE, template <class> class StoragePolicy >
6064
operator Matrix<RTYPE, StoragePolicy>() const {
61-
return Rf_allocMatrix(RTYPE, nr, nc);
65+
// Explicitly protect temporary matrix to avoid false positive
66+
// with rchk (#892)
67+
Shield<SEXP> x(Rf_allocMatrix(RTYPE, nr, nc));
68+
Matrix<RTYPE, PreserveStorage> ret(x);
69+
return ret;
6270
}
6371

6472
private:

0 commit comments

Comments
 (0)