Skip to content

Commit 22bec91

Browse files
committed
Merge #247: type-map: Work around LLVM 22 "out of bounds index" error
f61af48 type-map: Work around LLVM 22 "out of bounds index" error (Ryan Ofsky) Pull request description: This workaround is needed to fix "parameter pack may not be accessed at an out of bounds index" compile errors in bitcoin/bitcoin#29409 due in sanitizer jobs due to bitcoin/bitcoin#34660 which updates sanitizers to use LLVM 22 instead of LLVM 21: https://github.com/bitcoin/bitcoin/actions/runs/22501264518/job/65188721708?pr=29409 https://github.com/bitcoin/bitcoin/actions/runs/22501264518/job/65188721733?pr=29409 ```c++ /cxx_build/include/c++/v1/__fwd/tuple.h:40:52: error: a parameter pack may not be accessed at an out of bounds index 40 | using type _LIBCPP_NODEBUG = __type_pack_element<_Ip, _Tp...>; | ^ /cxx_build/include/c++/v1/__utility/try_key_extraction.h:82:67: note: in instantiation of template class 'std::tuple_element<0, std::tuple<>>' requested here 82 | is_same<__remove_const_ref_t<typename tuple_element<0, _Tuple1>::type>, _KeyT>::value, | ^ ``` The upstream LLVM bug is llvm/llvm-project#167709 and fix is llvm/llvm-project#183614 ACKs for top commit: hebasto: ACK f61af48, I have reviewed the code and it looks OK. Tree-SHA512: 19eec5cd304f6e585626fe39a85a82ef2b9b2f5ab1ca8b81c0836d76d3846eb9d4893c0766248251d9e685d49d4a5e84141377dad13888fa8268d78f5c9f7be5
2 parents 8a5e3ae + f61af48 commit 22bec91

1 file changed

Lines changed: 30 additions & 1 deletion

File tree

include/mp/type-map.h

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,35 @@ void CustomBuildField(TypeList<std::map<KeyLocalType, ValueLocalType>>,
2727
}
2828
}
2929

30+
// Replacement for `m.emplace(piecewise_construct, t1, t2)` to work around a
31+
// Clang 22 regression triggered by libc++'s std::map piecewise emplace: when
32+
// the key constructor argument tuple is empty (std::tuple<>), libc++'s internal
33+
// "try key extraction" SFINAE probe instantiates std::tuple_element<0,
34+
// std::tuple<>>, which Clang 22 diagnoses as an out-of-bounds pack access ("a
35+
// parameter pack may not be accessed at an out of bounds index") instead of
36+
// treating it as substitution failure. See LLVM issue #167709 and the upstream
37+
// fix in llvm/llvm-project PR #183614.
38+
// https://github.com/llvm/llvm-project/issues/167709
39+
// https://github.com/llvm/llvm-project/pull/183614
40+
template <class Map, class Tuple1, class Tuple2>
41+
auto EmplacePiecewiseSafe(
42+
Map& m,
43+
const std::piecewise_construct_t&,
44+
Tuple1&& t1,
45+
Tuple2&& t2)
46+
{
47+
if constexpr (std::tuple_size_v<std::remove_reference_t<Tuple1>> == 0) {
48+
// Avoid tuple<> / tuple<> (LLVM 22 libc++ regression path)
49+
return m.emplace(std::piecewise_construct,
50+
std::forward_as_tuple(typename Map::key_type{}),
51+
std::forward<Tuple2>(t2));
52+
} else {
53+
return m.emplace(std::piecewise_construct,
54+
std::forward<Tuple1>(t1),
55+
std::forward<Tuple2>(t2));
56+
}
57+
}
58+
3059
template <typename KeyLocalType, typename ValueLocalType, typename Input, typename ReadDest>
3160
decltype(auto) CustomReadField(TypeList<std::map<KeyLocalType, ValueLocalType>>,
3261
Priority<1>,
@@ -42,7 +71,7 @@ decltype(auto) CustomReadField(TypeList<std::map<KeyLocalType, ValueLocalType>>,
4271
Make<ValueField>(item),
4372
ReadDestEmplace(
4473
TypeList<std::pair<const KeyLocalType, ValueLocalType>>(), [&](auto&&... args) -> auto& {
45-
return *value.emplace(std::forward<decltype(args)>(args)...).first;
74+
return *EmplacePiecewiseSafe(value, std::forward<decltype(args)>(args)...).first;
4675
}));
4776
}
4877
});

0 commit comments

Comments
 (0)