diff --git a/NEWS.md b/NEWS.md index 5dbe9565..711dc612 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # clock (development version) +* Avoid non-API `SET_ATTRIB()`. + # clock 0.7.3 * `%Y`, `%F`, `%G`, and `%c` now parse up to 4 _characters_ by default, rather diff --git a/src/clock.h b/src/clock.h index c64bf69f..6e4f04ab 100644 --- a/src/clock.h +++ b/src/clock.h @@ -29,4 +29,13 @@ #define r_chr_na NA_STRING #define r_lgl_na NA_LOGICAL +#if R_VERSION < R_Version(4, 5, 0) +static inline +void CLEAR_ATTRIB(SEXP x) { + SET_ATTRIB(x, R_NilValue); + SET_OBJECT(x, 0); + UNSET_S4_OBJECT(x); +} +#endif + #endif diff --git a/src/rcrd.cpp b/src/rcrd.cpp index ca25ea8a..79058985 100644 --- a/src/rcrd.cpp +++ b/src/rcrd.cpp @@ -15,8 +15,8 @@ new_clock_rcrd_from_fields(SEXP fields, SEXP names, SEXP classes) { // Clear all attributes except for `names`, as we often // pass in other duration or time point objects as `fields` - SEXP field_names = Rf_getAttrib(fields, R_NamesSymbol); - SET_ATTRIB(fields, r_null); + SEXP field_names = PROTECT(Rf_getAttrib(fields, R_NamesSymbol)); + CLEAR_ATTRIB(fields); Rf_setAttrib(fields, R_NamesSymbol, field_names); const r_ssize n_fields = Rf_xlength(fields); @@ -54,7 +54,7 @@ new_clock_rcrd_from_fields(SEXP fields, SEXP names, SEXP classes) { SET_VECTOR_ELT(fields, 0, field0); } - UNPROTECT(1); + UNPROTECT(2); return fields; }