Conversation
kevinushey
left a comment
There was a problem hiding this comment.
Do these handle NAs? Or would these only ever be invoked for the "not NA" cases?
|
In principle, sugar functions already handle NAs, so these will be invoked for non-NA cases. But I haven't triaged all the cases yet, so we'll see. If this implementation looks good so far, I'll continue with that. |
|
BTW @eddelbuettel I don't see the sugar directory listed in Codecov. Isn't the covr workflow running all the tests? |
|
I don't think we exclude Sugar from tests or coverage. There is a specific entry point |
|
Yes, and it requires RunAllRcppTests set to yes, so I was wondering if the covr task is not setting it? |
|
BTW I was 'this month old' when I heard about the boo-boo with > Rcpp::evalCpp("std::numeric_limits<int>::min()") # normal
[1] NA
> Rcpp::evalCpp("std::numeric_limits<int>::max()") # normal
[1] 2147483647
> Rcpp::evalCpp("std::numeric_limits<int>::min() * 1.0") # also normal
[1] -2147483648
> Rcpp::evalCpp("std::numeric_limits<int>::min()") # R special
[1] NA
>
>
> Rcpp::evalCpp("std::numeric_limits<double>::min()") # WTF: positive number
[1] 2.22507e-308
> Rcpp::evalCpp("std::numeric_limits<double>::lowest()") # normal
[1] -1.79769e+308
>
> Rcpp::evalCpp("std::numeric_limits<int>::lowest()")
[1] NA
> Rcpp::evalCpp("std::numeric_limits<int>::lowest() * 1.0")
[1] -2147483648
> Mind you we are not running overflow for |
|
|
No, we are not. The overflow checks are enabled only for integral types. Because doubles do not overflow, they become |
So |
|
I validated the assumptions in |
Correct. |
I think that the coverage we see is just what calls into But anyway, this is another matter. We can discuss this further in another issue. |
|
Good thinking. Sounds like a testing / coverage package having all the tests in I never know what to of coverage. It's a metric, and as Goodhart told us decades ago, of course it is being gamed. |
There was a problem hiding this comment.
Pull request overview
This PR adds protection against integer overflows in Rcpp sugar functions by implementing safe arithmetic operations for addition, subtraction, and multiplication.
Changes:
- Introduces new
safe_math.hheader with safe arithmetic macros that detect and prevent integer overflows - Updates sugar operators and functions (
plus,minus,times,sum,cumsum,cumprod,diff,rowSums, etc.) to use the safe operations - Adds comprehensive tests to verify overflow detection in various contexts
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| inst/include/Rcpp/sugar/tools/safe_math.h | Implements safe arithmetic operations with overflow detection using compiler builtins or fallback logic |
| inst/include/Rcpp/sugar/sugar.h | Includes the new safe_math.h header |
| inst/include/Rcpp/sugar/operators/plus.h | Replaces direct addition with RCPP_SAFE_ADD macro |
| inst/include/Rcpp/sugar/operators/minus.h | Replaces direct subtraction with RCPP_SAFE_SUB macro |
| inst/include/Rcpp/sugar/operators/times.h | Replaces direct multiplication with RCPP_SAFE_MUL macro |
| inst/include/Rcpp/sugar/functions/sum.h | Uses safe addition for sum operations |
| inst/include/Rcpp/sugar/functions/cumsum.h | Uses safe addition for cumulative sum |
| inst/include/Rcpp/sugar/functions/cumprod.h | Uses safe multiplication for cumulative product |
| inst/include/Rcpp/sugar/functions/diff.h | Uses safe subtraction for diff operations |
| inst/include/Rcpp/sugar/functions/rowSums.h | Uses safe addition and refactors NA handling logic |
| inst/tinytest/test_sugar.R | Adds overflow detection tests for all modified operations |
| inst/tinytest/cpp/sugar.cpp | Adds test functions for overflow scenarios |
| inst/tinytest/cpp/sugar_safe_math.cpp | Tests safe math operations with builtin support |
| inst/tinytest/cpp/sugar_safe_math_fallback.cpp | Tests safe math operations with fallback implementation |
| ChangeLog | Documents the changes |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Here's what Claude has to say: |
Good catch, will fix.
Not sure about that. This code is a bit of a mess, and I would lie if I say I completely understand it, but empirically all cases are covered by tests (vector-vector, primitive-vector, vector-primitive), and these are instantiated for sequences. If I add the safe functions here, the sequence tests don't compile.
Yeap, fixed that, forgot to mention it. Will do. |
Closes #1454
Checklist
R CMD checkstill passes all tests