Skip to content

fix(cran): v3.1.1 — clear gcc-UBSAN additional issue (varPro test skip + vignette precompute)#119

Merged
ehrlinger merged 6 commits into
mainfrom
fix/cran-ubsan-varpro-skip
Jun 12, 2026
Merged

fix(cran): v3.1.1 — clear gcc-UBSAN additional issue (varPro test skip + vignette precompute)#119
ehrlinger merged 6 commits into
mainfrom
fix/cran-ubsan-varpro-skip

Conversation

@ehrlinger

@ehrlinger ehrlinger commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Why

CRAN flagged a gcc-UBSAN additional issue on ggRandomForests 3.1.0 (Ripley, 2026-06-12; correct before 2026-06-29):

entry.c:184:55: runtime error: pointer index expression with base
0x000000000001 overflowed to 0xfffffffffffffff9
    #0 rfsrcGrow .../randomForestSRC/src/entry.c:184

Root cause is upstream, in randomForestSRC (not us): rfsrcGrow does RF_yWeight = REAL(yWeight); RF_yWeight-- unconditionally. When yvar.wt arrives length-0 (the unsupervised family path every varPro rule-grow uses), REAL() returns R's 0x1 empty-vector sentinel and the -- forms an out-of-bounds pointer — UB that UBSAN flags (the pointer is never dereferenced). ggRandomForests is pure R (NeedsCompilation: no); it only surfaces the path by exercising varPro. Upstream maintainers are aware and staging a fix; root cause + suggested patch in dev/randomForestSRC-ubsan-report.md.

What this PR does

  1. Tests: the varPro test fixtures now skip_on_cran(), so they don't run on CRAN's check machines (incl. gcc-UBSAN). The memtest that flagged 3.1.0 ran only the test suite, so this resolves the reported issue.
  2. Vignette: the varpro vignette grew ~10 varPro forests live (varpro/uvarpro/isopro/ivarpro/beta.varpro). All are now precomputed into vignettes/varpro_precomputed.rds and loaded with a live fallback, so R CMD check performs no live varPro grow anywhere. Unused embedded forests ($rf, $isoforest, redundant ivarpro attrs) are stripped before saving — validated that every gg_* wrapper call returns output identical to the un-stripped object — keeping the file at 414 KB and the tarball at 4.13 MB (< CRAN's 5 MB).
  3. Docs: NEWS.md + cran-comments.md updated to describe both changes.

Verification

  • R CMD check --as-cran with manual: 0 errors, 0 warnings, 1 NOTE (days-since-update, expected and pre-explained in cran-comments).
  • examples / --run-donttest / tests / vignette rebuild: all OK.
  • Overall check time 2:43 (< 10-min budget); tarball 4.13 MB; urlchecker clean; 0 reverse deps; DESCRIPTION ↔ NEWS both 3.1.1.

Residual (intentional)

The .Rd varPro examples remain \donttest{} + requireNamespace()-guarded (the standard idiom). They run only under --run-donttest, not on normal CRAN checks, and were not the memtest trigger.

🤖 Generated with Claude Code

ehrlinger and others added 2 commits June 12, 2026 07:56
…1.1)

CRAN's gcc-UBSAN additional check flagged 3.1.0 with a 0-length array
access in randomForestSRC's compiled rfsrcGrow (entry.c:184), reached
when varPro::varpro()/beta.varpro() grow a forest in our tests.
ggRandomForests is pure R (NeedsCompilation: no) — the overflow is in a
dependency, surfaced by our tests.

Gate every varPro forest-growing test fixture/builder with
testthat::skip_on_cran() so CRAN's machines (incl. gcc-UBSAN) never run
them. No package code changed; the tests still run on CI and locally.
Bump to 3.1.1; NEWS + cran-comments explain the fix. Upstream reported.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.04%. Comparing base (0802143) to head (7b792c0).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #119   +/-   ##
=======================================
  Coverage   87.04%   87.04%           
=======================================
  Files          44       44           
  Lines        3938     3938           
=======================================
  Hits         3428     3428           
  Misses        510      510           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

The varpro vignette grew ~10 varPro forests live (varpro/uvarpro/isopro/
ivarpro/beta.varpro), each reaching randomForestSRC's rfsrcGrow rule-grow
path that trips the gcc-UBSAN "0-length array" report (entry.c:184, a
length-0 yvar.wt decremented to an out-of-bounds pointer). Cache every fit
in vignettes/varpro_precomputed.rds and load it with a live fallback, so
R CMD check performs no live varPro grow.

Strip the unused embedded forests ($rf, $isoforest, redundant ivarpro
attrs) before saving — validated that every gg_* wrapper call returns
output identical to the un-stripped object — keeping the file at 414 KB
(tarball 4.13 MB, under CRAN's 5 MB limit).

R CMD check --as-cran (with manual): 0 errors, 0 warnings, 1 NOTE
(days-since-update, expected). Overall check time 2:43.

dev/randomForestSRC-ubsan-report.md records the upstream root cause +
suggested patch (maintainers are aware and staging a fix).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ehrlinger ehrlinger changed the title fix(cran): v3.1.1 — skip_on_cran varPro tests to clear gcc-UBSAN fix(cran): v3.1.1 — clear gcc-UBSAN additional issue (varPro test skip + vignette precompute) Jun 12, 2026
@ehrlinger ehrlinger requested a review from Copilot June 12, 2026 14:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR prepares ggRandomForests v3.1.1 for CRAN by avoiding an upstream randomForestSRC gcc-UBSAN “additional issue” that is surfaced when ggRandomForests exercises varPro forest growth during checks.

Changes:

  • Skip varPro-growing tests on CRAN via testthat::skip_on_cran().
  • Precompute all varPro vignette fits into vignettes/varpro_precomputed.rds and load them with live fallbacks to avoid any live varPro grow during R CMD check.
  • Update release metadata and CRAN-facing documentation (DESCRIPTION/NEWS/cran-comments) and add an upstream UBSAN report note under dev/.

Reviewed changes

Copilot reviewed 9 out of 10 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
vignettes/varpro.qmd Loads precomputed varPro fits (with fallback) to avoid live forest growth during vignette rebuilds.
vignettes/precompute_varpro.R Script to generate and trim the precomputed vignette objects saved to varpro_precomputed.rds.
tests/testthat/test_gg_varpro.R Skips varPro-based gg_varpro tests on CRAN.
tests/testthat/test_gg_udependent.R Skips varPro-based gg_udependent tests on CRAN.
tests/testthat/helper-varpro-fixtures.R Skips varPro fixture generation on CRAN to avoid triggering upstream UBSAN.
NEWS.md Bumps version to 3.1.1 and documents the CRAN workaround approach.
dev/randomForestSRC-ubsan-report.md New developer note describing the upstream UBSAN issue and suggested patch.
DESCRIPTION Version/date bump for the 3.1.1 release.
cran-comments.md CRAN submission notes updated to explain the UBSAN workaround and test/vignette changes.
Comments suppressed due to low confidence (1)

tests/testthat/helper-varpro-fixtures.R:12

  • Adding skip_on_cran() here will also skip these fixtures under CI R CMD check unless NOT_CRAN=true is set. With the current workflow env, gg_beta_varpro-related tests that rely on these helpers will no longer run in CI either.
.varpro_mtcars <- function() {
  testthat::skip_on_cran()
  if (is.null(.varpro_cache$v)) {
    if (!requireNamespace("varPro", quietly = TRUE)) {
      testthat::skip("varPro not installed")
    }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/testthat/test_gg_varpro.R
Comment thread tests/testthat/test_gg_udependent.R
Comment thread vignettes/precompute_varpro.R Outdated
Comment thread vignettes/precompute_varpro.R Outdated
Comment thread NEWS.md Outdated
Comment thread cran-comments.md Outdated
ehrlinger and others added 3 commits June 12, 2026 10:10
Lint CI flagged 16 brace_linter/semicolon_linter issues in the vignette
hardening:
- varpro.qmd: the load-with-fallback chunks braced the `if` branch but not
  `else` (`} else .vp$x`); brace both branches to match the existing
  precomputed chunks.
- precompute_varpro.R: rewrite the one-line .strip_* helpers (compound
  semicolons + inline braces) as multi-line.

Behaviour-preserving; lint_package() now returns 0. The shipped
varpro_precomputed.rds is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot flagged that skip_on_cran() also skips under R CMD check in CI
(NOT_CRAN unset in the workflows), so the varPro tests run nowhere in CI:
- NEWS.md / cran-comments.md no longer claim the tests "run on CI"; they
  state the tests run locally (devtools::test()) and are skipped under
  R CMD check, including the CI check jobs. (Restoring CI coverage via
  NOT_CRAN=true is deferred to 3.1.2, coupled with the issue #118 fix so
  the intermittent survival gg_varpro test doesn't flake CI.)
- precompute_varpro.R: scope the "forests unused" comments — the survival
  C-path gg_partial_varpro() and gg_isopro(newdata=) DO use $rf/$isoforest,
  but the vignette never invokes those on a stripped object (pd_pbc cached,
  gg_isopro training-path only).

No behaviour change; lint_package() = 0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot noted skip_on_cran() also skips the varPro tests under R CMD check
in CI (NOT_CRAN unset), so they ran nowhere. Set NOT_CRAN=true in all
check/coverage workflows to restore that coverage. Safe: CI is not a
sanitizer build, so the upstream randomForestSRC UBSAN path is harmless
here; only CRAN's own check machines (NOT_CRAN unset) skip them, which is
what avoids the gcc-UBSAN additional issue. The CI-run varPro tests cover
regression + classification only (no survival), so issue #118 cannot flake
CI. Verified locally under NOT_CRAN=true: 0 failures across the varPro
suite.

NEWS.md / cran-comments.md restore the accurate "runs in CI and locally;
skipped only on CRAN" claim.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ehrlinger

Copy link
Copy Markdown
Owner Author

Resolved the Copilot review threads — all addressed in commits after the review (which ran against b088769e):

  • test_gg_varpro.R:9 / test_gg_udependent.R:9 (skip_on_cran also skips in CI) → 7b792c03: set NOT_CRAN=true in all check/coverage workflows, so the varPro tests now run in CI. Verified green on all platforms (Windows/macOS/Linux).
  • NEWS.md / cran-comments.md ("still run on CI" inaccurate) → 7b792c03 (+8a249161): with NOT_CRAN=true the claim is true again; wording updated to "run in CI and locally; skipped only on CRAN's check machines".
  • precompute_varpro.R strip comments (forests "never" used — survival C-path gg_partial_varpro() / gg_isopro(newdata=) do read $rf) → 8a249161: scoped the comments. Not a bug — the cached path never invokes those on a stripped object, and the live fallback grows full objects.

Also fixed the lint failure (d7c65af8): braced the vignette else fallbacks + multi-line .strip_* helpers. All 15 checks green.

@ehrlinger ehrlinger merged commit 168bd7c into main Jun 12, 2026
15 checks passed
@ehrlinger ehrlinger deleted the fix/cran-ubsan-varpro-skip branch June 12, 2026 16:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants