Skip to content

Commit 6e6ad56

Browse files
committed
Rcpp::stop() in exported wrappers only
Exported functions (thin wrappers) use Rcpp::stop() for input validation — the exception is caught immediately by BEGIN_RCPP/END_RCPP in the generated RcppExports wrapper. Implementation functions retain Rf_error() for defensive guards that should never be reached if wrappers validate correctly (LCOV_EXCL, This pattern avoids C++ exception unwinding through complex stack frames, which can cause std::terminate() on ARM. Revert "Rf_error →Rcpp:stop()" This reverts commit b20e03e. Test R-level guards instead of C++ error paths (ARM safety)
1 parent b20e03e commit 6e6ad56

File tree

7 files changed

+17
-29
lines changed

7 files changed

+17
-29
lines changed

src/day_1985.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ double calc_consensus_info(const List &trees, const LogicalVector &phylo,
9696

9797
std::vector<ClusterTable> tables;
9898
if (std::size_t(n_trees) > tables.max_size()) {
99-
Rcpp::stop("Not enough memory available to compute consensus of so many trees"); // LCOV_EXCL_LINE
99+
Rf_error("Not enough memory available to compute consensus of so many trees"); // LCOV_EXCL_LINE
100100
}
101101

102102
tables.reserve(n_trees);

src/hpart.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ size_t build_node_from_list(const RObject& node,
126126
if (Rf_isInteger(node) || Rf_isReal(node)) {
127127
const IntegerVector leaf_vec(node);
128128
if (leaf_vec.size() != 1) {
129-
Rcpp::stop("List must only contain integers, not vectors of integers"); // #nocov
129+
Rf_error("List must only contain integers, not vectors of integers"); // #nocov
130130
}
131131
const int leaf_label = leaf_vec[0]; // 1-based R leaf label
132132
const size_t leaf_idx = leaf_label - 1; // 0-based label for HNode
@@ -172,7 +172,7 @@ size_t build_node_from_list(const RObject& node,
172172
}
173173

174174
// Invalid node type
175-
Rcpp::stop("Invalid node type"); // #nocov
175+
Rf_error("Invalid node type"); // #nocov
176176
}
177177

178178

src/hpart_relabel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ void recompute_bitsets_postorder(TreeDist::HPart &hpart, const size_t node_idx,
1313
if (node.children.empty()) {
1414
// Leaf node
1515
if (node.leaf_count != 1) {
16-
Rcpp::stop("Leaf node has leaf_count != 1"); // #nocov
16+
Rf_error("Leaf node has leaf_count != 1"); // #nocov
1717
}
1818
int new_index = mapping[node.label]; // mapping is 0-based
1919
node.label = new_index;

src/information.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ __attribute__((constructor))
4949
inline double split_phylo_info(const int32 n_in, const int32 *n_tip,
5050
const double p) {
5151
if (*n_tip > CT_MAX_LEAVES) {
52-
Rcpp::stop("This many leaves are not yet supported.");
52+
Rf_error("This many leaves are not yet supported.");
5353
}
5454
const int32 n_out = *n_tip - n_in;
5555
assert(p > 0);
@@ -75,7 +75,7 @@ inline double split_phylo_info(const int32 n_in, const int32 *n_tip,
7575
inline double split_clust_info(const int32 n_in, const int32 *n_tip,
7676
const double p) {
7777
if (*n_tip > CT_MAX_LEAVES) {
78-
Rcpp::stop("This many leaves are not yet supported.");
78+
Rf_error("This many leaves are not yet supported.");
7979
}
8080
const int32 n_out = *n_tip - n_in;
8181
assert(p > 0);

src/nni_distance.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -226,16 +226,7 @@ grf_match nni_rf_matching (
226226

227227
ASSERT(n_splits > 0);
228228
ASSERT(n_tips > 3);
229-
if (n_tips > NNI_MAX_TIPS) {
230-
Rcpp::stop("Cannot calculate NNI distance for trees with so many tips.");
231-
}
232-
233-
// #nocov start
234-
if (static_cast<int64_t>(n_splits) * static_cast<int64_t>(n_bins) >
235-
static_cast<int64_t>(std::numeric_limits<int32_t>::max())) {
236-
Rcpp::stop("Cannot calculate NNI distance for trees with so many splits.");
237-
}
238-
// #nocov end
229+
ASSERT(n_tips <= NNI_MAX_TIPS); // Validated by exported wrapper
239230

240231
const int32_t last_bin = n_bins - 1;
241232
const int32_t unset_tips = (n_tips % SL_BIN_SIZE) ?
@@ -317,7 +308,7 @@ IntegerVector cpp_nni_distance(const IntegerMatrix& edge1,
317308

318309
if (n_edge != int32_t(edge2.nrow())) {
319310
Rcpp::stop("Both trees must have the same number of edges. "
320-
"Is one rooted and the other unrooted?");
311+
"Is one rooted and the other unrooted?");
321312
}
322313

323314
if (n_tip < 4) {

src/spr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ IntegerVector confusion(const RawMatrix& x, const RawMatrix& y) {
119119

120120
IntegerMatrix reverse (const IntegerMatrix x) {
121121
if (double(x.nrow()) > double(std::numeric_limits<intx>::max())) {
122-
Rcpp::stop("This many edges are not (yet) supported.");
122+
Rf_error("This many edges are not (yet) supported."); // impl guard; wrapper validates
123123
}
124124
const intx n_edge = intx(x.nrow());
125125
ASSERT(n_edge % 2 == 0); // Tree is binary

src/tree_distances.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ namespace TreeDist {
2929

3030
void check_ntip(const double n) {
3131
if (n > static_cast<double>(std::numeric_limits<int16>::max())) {
32-
Rf_error("This many tips are not (yet) supported."); // not Rcpp::stop: ARM safety
32+
Rcpp::stop("This many tips are not (yet) supported.");
3333
}
3434
}
3535

@@ -602,14 +602,11 @@ inline List shared_phylo (const RawMatrix &x, const RawMatrix &y,
602602
_["matching"] = final_matching);
603603
}
604604

605-
// Input validation: Rf_error (longjmp) instead of Rcpp::stop (C++ exception)
606-
// for ARM compatibility. R callers should validate before reaching C++.
607-
608605
// [[Rcpp::export]]
609606
List cpp_robinson_foulds_distance(const RawMatrix &x, const RawMatrix &y,
610607
const IntegerVector &nTip) {
611608
if (x.cols() != y.cols()) {
612-
Rf_error("Input splits must address same number of tips.");
609+
Rcpp::stop("Input splits must address same number of tips.");
613610
}
614611
return robinson_foulds_distance(x, y, static_cast<int32>(nTip[0]));
615612
}
@@ -618,7 +615,7 @@ List cpp_robinson_foulds_distance(const RawMatrix &x, const RawMatrix &y,
618615
List cpp_robinson_foulds_info(const RawMatrix &x, const RawMatrix &y,
619616
const IntegerVector &nTip) {
620617
if (x.cols() != y.cols()) {
621-
Rf_error("Input splits must address same number of tips.");
618+
Rcpp::stop("Input splits must address same number of tips.");
622619
}
623620
const int32 n_tip = static_cast<int32>(nTip[0]);
624621
TreeDist::check_ntip(n_tip);
@@ -629,7 +626,7 @@ List cpp_robinson_foulds_info(const RawMatrix &x, const RawMatrix &y,
629626
List cpp_matching_split_distance(const RawMatrix &x, const RawMatrix &y,
630627
const IntegerVector &nTip) {
631628
if (x.cols() != y.cols()) {
632-
Rf_error("Input splits must address same number of tips.");
629+
Rcpp::stop("Input splits must address same number of tips.");
633630
}
634631
const int32 n_tip = static_cast<int32>(nTip[0]);
635632
TreeDist::check_ntip(n_tip);
@@ -641,7 +638,7 @@ List cpp_jaccard_similarity(const RawMatrix &x, const RawMatrix &y,
641638
const IntegerVector &nTip, const NumericVector &k,
642639
const LogicalVector &allowConflict) {
643640
if (x.cols() != y.cols()) {
644-
Rf_error("Input splits must address same number of tips.");
641+
Rcpp::stop("Input splits must address same number of tips.");
645642
}
646643
const int32 n_tip = static_cast<int32>(nTip[0]);
647644
TreeDist::check_ntip(n_tip);
@@ -652,7 +649,7 @@ List cpp_jaccard_similarity(const RawMatrix &x, const RawMatrix &y,
652649
List cpp_msi_distance(const RawMatrix &x, const RawMatrix &y,
653650
const IntegerVector &nTip) {
654651
if (x.cols() != y.cols()) {
655-
Rf_error("Input splits must address same number of tips.");
652+
Rcpp::stop("Input splits must address same number of tips.");
656653
}
657654
const int32 n_tip = static_cast<int32>(nTip[0]);
658655
TreeDist::check_ntip(n_tip);
@@ -663,7 +660,7 @@ List cpp_msi_distance(const RawMatrix &x, const RawMatrix &y,
663660
List cpp_mutual_clustering(const RawMatrix &x, const RawMatrix &y,
664661
const IntegerVector &nTip) {
665662
if (x.cols() != y.cols()) {
666-
Rf_error("Input splits must address same number of tips.");
663+
Rcpp::stop("Input splits must address same number of tips.");
667664
}
668665
const int32 n_tip = static_cast<int32>(nTip[0]);
669666
TreeDist::check_ntip(n_tip);
@@ -674,7 +671,7 @@ List cpp_mutual_clustering(const RawMatrix &x, const RawMatrix &y,
674671
List cpp_shared_phylo(const RawMatrix &x, const RawMatrix &y,
675672
const IntegerVector &nTip) {
676673
if (x.cols() != y.cols()) {
677-
Rf_error("Input splits must address same number of tips.");
674+
Rcpp::stop("Input splits must address same number of tips.");
678675
}
679676
const int32 n_tip = static_cast<int32>(nTip[0]);
680677
TreeDist::check_ntip(n_tip);

0 commit comments

Comments
 (0)