Skip to content

Guard runtime Buffer::offset_of calculation past rank bounds - #9701

Open
ShaddyDC wants to merge 1 commit into
halide:mainfrom
ShaddyDC:guard-buffer-offset-of-rank-bounds
Open

ShaddyDC wants to merge 1 commit into
halide:mainfrom
ShaddyDC:guard-buffer-offset-of-rank-bounds

Conversation

@ShaddyDC

Copy link
Copy Markdown

Unlike the pointer overload offset_of(const int *), which loops strictly over 0 <= i < this->dimensions(), the variadic Halide::Runtime::Buffer::offset_of(int d, int first, Args... rest) overload previously indexed this->buf.dim[d] without checking whether d had already reached this->dimensions(). For Buffer<T, AnyDims>, passing more coordinates than dimensions() reads uninitialized shape[d] storage (for d < InClassDimStorage) or reads out-of-bounds past buf.dim (for d >= InClassDimStorage or external halide_buffer_t descriptors).

Guard offset_of when d >= this->dimensions() so it asserts under HALIDE_RUNTIME_BUFFER_CHECK_INDICES (matching the compile-time static_assert on fixed-rank Buffer<T, Dims>) and returns 0 without reading this->buf.dim[d] when runtime index checks are disabled. Also update the 0-D scalar buffer check in correctness_lerp (test/correctness/lerp.cpp) from result(0) to result().

Generated with Gemini 4 gemini-code-assist@google.com

Unlike the pointer overload `offset_of(const int *)`, which loops strictly over `0 <= i < this->dimensions()`, the variadic `Halide::Runtime::Buffer::offset_of(int d, int first, Args... rest)` overload previously indexed `this->buf.dim[d]` without checking whether `d` had already reached `this->dimensions()`. For `Buffer<T, AnyDims>`, passing more coordinates than `dimensions()` reads uninitialized `shape[d]` storage (for `d < InClassDimStorage`) or reads out-of-bounds past `buf.dim` (for `d >= InClassDimStorage` or external `halide_buffer_t` descriptors).

Guard `offset_of` when `d >= this->dimensions()` so it asserts under `HALIDE_RUNTIME_BUFFER_CHECK_INDICES` (matching the compile-time `static_assert` on fixed-rank `Buffer<T, Dims>`) and returns `0` without reading `this->buf.dim[d]` when runtime index checks are disabled. Also update the 0-D scalar buffer check in `correctness_lerp` (`test/correctness/lerp.cpp`) from `result(0)` to `result()`.

Co-authored-by: Gemini 4 <gemini-code-assist@google.com>
@abadams

abadams commented Nov 13, 2026

Copy link
Copy Markdown
Member

Thanks for the PR! This code is intended to go in hot loops, and any kind of branching here is likely to break autovectorization of those loops. Please just assert d < dimensions() in the existing ifdef block

This branch has not been deployed

No deployments
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