Merge bitcoin/bitcoin#34161: refactor: avoid possible UB from std::distance for nullptr args

477c5504e05f9031449cdbf62bf329eac427cb0c  coins: replace `std::distance` with unambiguous pointer subtraction (Lőrinc)

Pull request description:

  ### Problem

  Calling `std::distance(nullptr, nullptr)` has ambiguous status in the C++ standard [iterator.requirements.general](https://eel.is/c++draft/iterator.requirements.general#7):
  > Iterators can also have singular values that are not associated with any sequence. Results of most expressions are undefined for singular values.

  It seems to work correctly in every implementation we use, but [LWG 1213](https://cplusplus.github.io/LWG/issue1213) ("Meaning of valid and singular iterator underspecified") has been Open since 2009, acknowledging that the standard's wording on this topic is unclear.

  <details>
  <summary>Details</summary>

  The [iterator.requirements.general](https://eel.is/c++draft/iterator.requirements.general#7) states:
  > Iterators can also have singular values that are not associated with any sequence. Results of most expressions are undefined for singular values.

  And [LWG 208](https://cplusplus.github.io/LWG/issue208)'s rationale explicitly confirms:
  > Null pointers are singular.

  Therefore they cannot form a valid range required by [std::distance](https://eel.is/c++draft/iterator.operations#4):
  > Preconditions: last is reachable from first, or InputIterator meets the Cpp17RandomAccessIterator requirements and first is reachable from last.

  </details>

  ### Fix

  A previous version of this PR checked both values for `nullptr`, the current one uses unambiguously well-defined pointer subtraction instead, which is per [expr.add](https://eel.is/c++draft/expr.add#5):
  > If P and Q both evaluate to null pointer values, the value is 0.

  This applies on the first call before any memory is allocated, when both pointers are `nullptr`.
  Using `operator-` directly is simpler and avoids the ambiguity entirely.

ACKs for top commit:
  maflcko:
    review ACK 477c5504e05f9031449cdbf62bf329eac427cb0c 🍶
  optout21:
    ACK 477c5504e05f9031449cdbf62bf329eac427cb0c
  sedited:
    ACK 477c5504e05f9031449cdbf62bf329eac427cb0c

Tree-SHA512: 5edfb19ab4820e2003928f60f20d4a5893bcd3c316afdfe91c9c06e9b465352769b2cddb0d0e2419ea083a906d35f4aada74149e81f4ea0315f8173ac538789f
This commit is contained in:
merge-script 2026-01-28 11:41:55 +01:00
commit 289d60f5ab
No known key found for this signature in database
GPG Key ID: 9B79B45691DB4173

View File

@ -155,7 +155,7 @@ class PoolResource final
void AllocateChunk()
{
// if there is still any available memory left, put it into the freelist.
size_t remaining_available_bytes = std::distance(m_available_memory_it, m_available_memory_end);
size_t remaining_available_bytes = m_available_memory_end - m_available_memory_it;
if (0 != remaining_available_bytes) {
ASAN_UNPOISON_MEMORY_REGION(m_available_memory_it, sizeof(ListNode));
PlacementAddToList(m_available_memory_it, m_free_lists[remaining_available_bytes / ELEM_ALIGN_BYTES]);