Skip to content

Commit d60ba3f

Browse files
authored
Rank Many Fix + Memory Sanitizer Build Flag (#847)
* Add Memory Sanitizer Option Memory Sanitizer has some false positives, but it did catch a bug. Further work with the memory sanitizer should involve automatic accounting for the false positives. * Bugfix for roaring_bitmap_rank_many (N in N out) (Problem found with Memory Sanitizer, fix by Claude Sonnet 4.6) The interface contract of roaring_bitmap_rank_many() is unambiguous: for N sorted inputs you should get N ranks out, one per input, in order. The bug is that the implementation doesn't honor that contract in the case where one or more trailing input values have xhigh greater than every key. The loop's exit condition (i < size && iter != end) lets i run out before iter does, and when that happens the function just returns early having silently skipped writing to the remaining ans slots, even though the caller was promised an answer for every input. What should happen for those leftover values is straightforward: if a query value's high bits exceed every container key in the bitmap, that value is greater than every element the bitmap holds, so its rank is just the bitmap's total cardinality, which is exactly what size holds once the loop has walked through all containers (each xhigh > key branch step added that container's cardinality to size). So the fix just applies the same logic the function already uses (rank = accumulated size) to the queries that fall off the end.
1 parent d81c639 commit d60ba3f

3 files changed

Lines changed: 13 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ option(ROARING_BUILD_C_TESTS_AS_CPP "Build test C files using C++ compilation" O
5252
option(ROARING_SANITIZE "Sanitize addresses" OFF)
5353
option(ROARING_SANITIZE_THREADS "Sanitize threads" OFF)
5454
option(ROARING_SANITIZE_UNDEFINED "Sanitize undefined behaviors" OFF)
55+
option(ROARING_SANITIZE_MEMORY "Sanitize memory (MemorySanitizer)" OFF)
5556
option(ROARING_UNSAFE_FROZEN_TESTS "If ON, tests some frozen functions which are unsafe as they include unaligned reads, this can cause crashes" OFF)
5657

5758
option(ENABLE_ROARING_TESTS "If OFF, disable unit tests altogether" ON)

src/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,11 @@ if(ROARING_SANITIZE_THREADS)
147147
target_compile_options(roaring PUBLIC -fsanitize=thread -fno-sanitize-recover=all)
148148
target_link_libraries(roaring PUBLIC -fsanitize=thread -fno-sanitize-recover=all)
149149
endif()
150+
if(ROARING_SANITIZE_MEMORY)
151+
if(NOT (CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
152+
message(FATAL_ERROR "ROARING_SANITIZE_MEMORY requires Clang/LLVM (MemorySanitizer). Configure with CC=clang CXX=clang++.")
153+
endif()
154+
message(STATUS "Enabling memory sanitizer")
155+
target_compile_options(roaring PUBLIC -fsanitize=memory -fno-omit-frame-pointer -fno-sanitize-recover=all)
156+
target_link_libraries(roaring PUBLIC -fsanitize=memory -fno-omit-frame-pointer -fno-sanitize-recover=all)
157+
endif()

src/roaring.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2823,6 +2823,10 @@ void roaring_bitmap_rank_many(const roaring_bitmap_t *bm, const uint32_t *begin,
28232823
iter++;
28242824
}
28252825
}
2826+
while (iter != end) { // must have N outputs for N inputs...
2827+
*(ans++) = size; // ...everything left is beyond all containers
2828+
iter++;
2829+
}
28262830
}
28272831

28282832
/**

0 commit comments

Comments
 (0)