From: Zygo Blaxell Date: Sun, 3 May 2026 18:52:19 +0000 (-0400) Subject: progress: work around GCC-16 -Warray-bounds bug X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d53565c74d3b1db9e035f55c5d67868147b568f;p=bees progress: work around GCC-16 -Warray-bounds bug `make_shared()` keeps triggering GCC bugs. The latest failure on GCC-16.0 and GCC-16.1: /usr/include/c++/16.1.1/bits/stl_tree.h:1383:19: error: array subscript 1 is outside array bounds of ‘std::_Sp_counted_ptr_inplace::ProgressHolderState, std::allocator, __gnu_cxx::_S_atomic> [1]’ [-Werror=array-bounds=] ../include/crucible/progress.h:46:24: error: array subscript ‘crucible::ProgressTracker::ProgressTrackerState[0]’ is partly outside array bounds of ‘unsigned char [40]’ [-Werror=array-bounds=] The regression is already reported to the GCC project: https://www.mail-archive.com/gcc-bugs%40gcc.gnu.org/msg895281.html https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123912 (and its duplicates) The problem is that GCC's static analyzer forgets that make_shared intentionally allocated a control block and an object in the same allocation, and thinks that accesses beyond the end of the control block are out-of-bounds array accesses. This workaround is the shortest: start with a unique_ptr (which has no control block but does have an exception-safe allocator), then convert to shared_ptr. This breaks the allocation into two parts so that GCC is no longer confused. As there are typically fewer than 10k progress tracking items, the separate control blocks will only add a few hundred KiB of RAM usage. Signed-off-by: Zygo Blaxell --- diff --git a/include/crucible/progress.h b/include/crucible/progress.h index a9fd003f..9d27b636 100644 --- a/include/crucible/progress.h +++ b/include/crucible/progress.h @@ -90,7 +90,7 @@ namespace crucible { template ProgressTracker::ProgressTracker(const ProgressTracker::value_type &t) : - m_state(make_shared()) + m_state(make_unique()) { m_state->m_begin = t; m_state->m_end = t;