Compile RMM with -Wsign-conversion#2308
Conversation
…resource.hpp Downstream projects compiling with -Wsign-conversion -Werror failed to build when including rmm headers due to implicit int -> size_t conversions: - detail/format.hpp: index declared as int but passed to std::array::at() - mr/detail/stream_ordered_memory_resource.hpp: get_num_cuda_devices() and device_id.value() (both int) used where size_t is expected Adds rmm::detail::safe_cast<To>() which asserts the value is non-negative before widening to an unsigned type, and uses it at the two call sites in stream_ordered_memory_resource.hpp. Changes index in format_bytes directly to std::size_t since it only ever increments from zero. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughReplaced implicit int→std::size_t conversions with explicit Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
cpp/include/rmm/detail/safe_cast.hpp (1)
14-30: Documentation claims broader checking than implementation provides.The docstring states this is a "Checked narrowing/sign-converting cast" that asserts the value is "representable in
To", but the implementation only checks for negative values when converting signed→unsigned. Narrowing conversions (e.g.,int64_t→int32_t) are not validated and could silently overflow.For the current PR use cases (widening
int→std::size_t), this is sufficient. Consider either:
- Updating the docstring to reflect the actual scope (sign-converting only), or
- Adding a narrowing check for completeness.
Option 1: Update documentation to match implementation
/** - * `@brief` Checked narrowing/sign-converting cast. + * `@brief` Checked sign-converting cast for widening integral conversions. * - * Casts `value` to type `To`, asserting at runtime that the value is - * representable in `To`. In release builds the assertion compiles away when + * Casts `value` to type `To`, asserting at runtime that signed values are + * non-negative when converting to unsigned types. In release builds the assertion compiles away when * the compiler can prove it is always true. */Option 2: Add narrowing check for full representability
template <typename To, typename From> [[nodiscard]] constexpr To safe_cast(From value) { static_assert(std::is_integral_v<From> && std::is_integral_v<To>, "safe_cast is only defined for integral types"); if constexpr (std::is_signed_v<From> && std::is_unsigned_v<To>) { RMM_EXPECTS(value >= From{0}, "safe_cast: negative value cannot be represented as unsigned"); } + if constexpr (sizeof(From) > sizeof(To) || + (std::is_signed_v<From> == std::is_signed_v<To> && sizeof(From) == sizeof(To))) { + // Potentially narrowing; check bounds + RMM_EXPECTS(value <= static_cast<From>(std::numeric_limits<To>::max()) && + value >= static_cast<From>(std::numeric_limits<To>::min()), + "safe_cast: value out of range for target type"); + } return static_cast<To>(value); }Note: Option 2 would require adding
#include <limits>.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cpp/include/rmm/detail/safe_cast.hpp` around lines 14 - 30, The docstring overstates checks—implement full representability checks in safe_cast instead of only signed→unsigned negative checks: include <limits> and inside template safe_cast add constexpr branches that for narrowing conversions (when sizeof(To) < sizeof(From) or differing signedness) verify value <= std::numeric_limits<To>::max() and value >= std::numeric_limits<To>::min() as applicable, using RMM_EXPECTS for failures; retain the existing negative check for signed→unsigned but expand logic to cover signed→signed, unsigned→unsigned, and unsigned→signed by comparing against numeric_limits<To>::min()/max() (convert bounds to From for comparison) so all integral representability is asserted before static_cast in safe_cast.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@cpp/include/rmm/detail/safe_cast.hpp`:
- Around line 14-30: The docstring overstates checks—implement full
representability checks in safe_cast instead of only signed→unsigned negative
checks: include <limits> and inside template safe_cast add constexpr branches
that for narrowing conversions (when sizeof(To) < sizeof(From) or differing
signedness) verify value <= std::numeric_limits<To>::max() and value >=
std::numeric_limits<To>::min() as applicable, using RMM_EXPECTS for failures;
retain the existing negative check for signed→unsigned but expand logic to cover
signed→signed, unsigned→unsigned, and unsigned→signed by comparing against
numeric_limits<To>::min()/max() (convert bounds to From for comparison) so all
integral representability is asserted before static_cast in safe_cast.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 160181ea-f492-4399-bdc1-dd581340a724
📒 Files selected for processing (3)
cpp/include/rmm/detail/format.hppcpp/include/rmm/detail/safe_cast.hppcpp/include/rmm/mr/detail/stream_ordered_memory_resource.hpp
Replace C++20 requires clause and std::in_range with a C++17-compatible implementation using std::numeric_limits and if constexpr. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ource.hpp Remove safe_cast.hpp and replace with static_cast<std::size_t> at the two affected call sites. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
I almost forgot to ask:
Please update these to enforce this requirement, too:
Lines 127 to 129 in 22d812c
Lines 12 to 13 in 22d812c
rmm/cpp/benchmarks/CMakeLists.txt
Lines 12 to 13 in 22d812c
Yup working on that now. There are more bugs to fix |
-Wsign-conversion
-Wsign-conversion -Wsign-conversion
Enables -Wsign-conversion -Werror across the library, tests, and benchmarks. Fixes all violations in rmm-owned code: - fixed_size_memory_resource.hpp: block_gen lambda index int -> size_t - statistics_resource_adaptor.hpp: cast bytes to int64_t for counter +=/-= - mr_ref_test.hpp: fix index type and std::next difference_type cast - mr_ref_test_mt.hpp: cast num_devices to size_t for vector::reserve - tracking_mr_tests.cpp: cast loop index for vector subscript - prefetch_tests.cpp: cast size_t to ptrdiff_t for std::next - log_parser.hpp: cast stoll result to uintptr_t rapidcsv.h and logger_tests.cpp (which includes it via log_parser.hpp) are suppressed per-target as rapidcsv.h is vendored third-party code. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@cpp/benchmarks/utilities/log_parser.hpp`:
- Line 149: The parse_pointer lambda currently uses std::stoll to parse hex
pointer strings into uintptr_t which can overflow for high-bit values; change
the call to std::stoull so unsigned parsing is used (keep the "(nil)" check) and
cast the result to uintptr_t (e.g. replace the std::stoll call with std::stoull
while leaving the ternary and static_cast<uintptr_t> intact) in the
parse_pointer/ptr assignment.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: f73316ca-0937-450e-a46a-c5cb11da26d9
📒 Files selected for processing (10)
cpp/CMakeLists.txtcpp/benchmarks/CMakeLists.txtcpp/benchmarks/utilities/log_parser.hppcpp/include/rmm/mr/fixed_size_memory_resource.hppcpp/include/rmm/mr/statistics_resource_adaptor.hppcpp/tests/CMakeLists.txtcpp/tests/mr/mr_ref_test.hppcpp/tests/mr/mr_ref_test_mt.hppcpp/tests/mr/tracking_mr_tests.cppcpp/tests/prefetch_tests.cpp
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…t711/rmm into fix-sign-conversion-warnings
There was a problem hiding this comment.
This is vendored -- no need to review its diff.
|
/merge |
Description
Compiles rmm with
-Wsign-conversion -Werrorand fixes the failuresChecklist