Skip to content

Commit 7203f32

Browse files
romainfrancoiseddelbuettel
authored andcommitted
AttributeProxy::set() (#947)
* AttributeProxy::set() fix * no need to Shield<> in meat * slightly nicer to inline Shield<> * Vector(SEXP) needs to protect `x` because `r_cast()` allocates. * safer NameProxy::set(). rchk. * safer clone<> * safer Vector ctors with various Shield<SEXP>
1 parent 08344ae commit 7203f32

File tree

6 files changed

+17
-11
lines changed

6 files changed

+17
-11
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ template <typename CLASS>
3030
template <typename T>
3131
typename AttributeProxyPolicy<CLASS>::AttributeProxy&
3232
AttributeProxyPolicy<CLASS>::AttributeProxy::operator=(const T& rhs) {
33-
set(Shield<SEXP>(wrap(rhs)));
33+
set(wrap(rhs));
3434
return *this;
3535
}
3636

inst/include/Rcpp/clone.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ namespace Rcpp{
3131
- T has a SEXP constructor
3232
*/
3333
template <typename T> T clone(const T& object) {
34-
SEXP x = const_cast<T&>(object) ;
35-
return T( Rf_duplicate( x ) ) ;
34+
Shield<SEXP> x(const_cast<T&>(object));
35+
Shield<SEXP> copy(Rf_duplicate(x));
36+
return T((SEXP)copy);
3637
}
3738

3839
} // namespace Rcpp

inst/include/Rcpp/proxy/AttributeProxy.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class AttributeProxyPolicy {
4949
return Rf_getAttrib( parent, attr_name ) ;
5050
}
5151
void set(SEXP x ){
52-
Rf_setAttrib( parent, attr_name, x ) ;
52+
Rf_setAttrib( parent, attr_name, Shield<SEXP>(x) ) ;
5353
}
5454
} ;
5555

inst/include/Rcpp/proxy/NamesProxy.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,16 @@ class NamesProxyPolicy{
4747
}
4848

4949
void set(SEXP x) {
50+
Shield<SEXP> safe_x(x);
51+
5052
/* check if we can use a fast version */
5153
if( TYPEOF(x) == STRSXP && parent.size() == Rf_length(x) ){
52-
SEXP y = parent.get__() ;
53-
Rf_setAttrib( y, R_NamesSymbol, x ) ;
54+
Rf_namesgets(parent, x);
5455
} else {
5556
/* use the slower and more flexible version (callback to R) */
5657
SEXP namesSym = Rf_install( "names<-" );
57-
Shield<SEXP> new_vec(Rcpp_fast_eval(Rf_lang3(namesSym, parent, x), R_GlobalEnv));
58+
Shield<SEXP> call(Rf_lang3(namesSym, parent, x));
59+
Shield<SEXP> new_vec(Rcpp_fast_eval(call, R_GlobalEnv));
5860
parent.set__(new_vec);
5961
}
6062

inst/include/Rcpp/vector/Matrix.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class Matrix : public Vector<RTYPE, StoragePolicy>, public MatrixBase<RTYPE, tru
5050

5151
Matrix() : VECTOR(Dimension(0, 0)), nrows(0) {}
5252

53-
Matrix(SEXP x) : VECTOR( r_cast<RTYPE>( x ) ), nrows( VECTOR::dims()[0] ) {}
53+
Matrix(SEXP x) : VECTOR(x), nrows( VECTOR::dims()[0] ) {}
5454

5555
Matrix( const Dimension& dims) : VECTOR( Rf_allocMatrix( RTYPE, dims[0], dims[1] ) ), nrows(dims[0]) {
5656
if( dims.size() != 2 ) throw not_a_matrix();

inst/include/Rcpp/vector/Vector.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,14 @@ class Vector :
7171
}
7272

7373
Vector( SEXP x ) {
74-
Storage::set__( r_cast<RTYPE>(x) ) ;
74+
Rcpp::Shield<SEXP> safe(x);
75+
Storage::set__( r_cast<RTYPE>(safe) ) ;
7576
}
7677

7778
template <typename Proxy>
7879
Vector( const GenericProxy<Proxy>& proxy ){
79-
Storage::set__( r_cast<RTYPE>(proxy.get()) ) ;
80+
Rcpp::Shield<SEXP> safe(proxy.get());
81+
Storage::set__( r_cast<RTYPE>(safe) ) ;
8082
}
8183

8284
explicit Vector( const no_init_vector& obj) {
@@ -174,7 +176,8 @@ class Vector :
174176

175177
template <bool NA, typename T>
176178
Vector( const sugar::SingleLogicalResult<NA,T>& obj ) {
177-
Storage::set__( r_cast<RTYPE>( const_cast<sugar::SingleLogicalResult<NA,T>&>(obj).get_sexp() ) ) ;
179+
Rcpp::Shield<SEXP> safe(const_cast<sugar::SingleLogicalResult<NA,T>&>(obj).get_sexp() );
180+
Storage::set__( r_cast<RTYPE>(safe) ) ;
178181
RCPP_DEBUG_2( "Vector<%d>( const sugar::SingleLogicalResult<NA,T>& ) [T = %s]", RTYPE, DEMANGLE(T) )
179182
}
180183

0 commit comments

Comments
 (0)