<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/61122>61122</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[ADT][Sequence] SafeIntIterator fails to compile within libc++'s debug functions
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
kuhar
</td>
</tr>
</table>
<pre>
Originally reported by @jayfoad in https://reviews.llvm.org/D144420#4164373.
Isolated repro (can be added to `SequenceTest.cpp`):
```c++
TEST(SequenceTest, Repro) {
std::vector<int> vals = {1, 2, 3};
detail::SafeIntIterator<int, false> begin(4);
detail::SafeIntIterator<int, false> end(6);
vals.insert(vals.end(), begin, end);
EXPECT_THAT(vals, ElementsAre(1, 2, 3, 4, 5));
}
```
Configure llvm with `-DCMAKE_BUILD_TYPE=Debug -DLLVM_ENABLE_EXPENSIVE_CHECKS=1 -DCMAKE_CXX_COMPILER=clang++-14 -DCMAKE_C_COMPILER=clang-14`.
Compile command: `ninja ADTTests`
Compilation error:
```
FAILED: unittests/ADT/CMakeFiles/ADTTests.dir/SequenceTest.cpp.o
ccache /usr/bin/clang++-14 -DEXPENSIVE_CHECKS -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_DEBUG -D_GNU_SOURCE -D_LIBCPP_ENABLE_ASSERTIONS -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/usr/local/google/home/kubak/llvm/build-debug/unittests/ADT -I/usr/local/google/home/kubak/llvm/llvm-project/llvm/unittests/ADT -I/usr/local/google/home/kubak/llvm/build-debug/include -I/usr/local/google/home/kubak/llvm/llvm-project/llvm/include -I/usr/local/google/home/kubak/llvm/llvm-project/third-party/unittest/googletest/include -I/usr/local/google/home/kubak/llvm/llvm-project/third-party/unittest/googlemock/include -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color -g -Wno-variadic-macros -Wno-gnu-zero-variadic-macro-arguments -fno-exceptions -fno-rtti -gsplit-dwarf -Wno-suggest-override -std=c++17 -MD -MT unittests/ADT/CMakeFiles/ADTTests.dir/SequenceTest.cpp.o -MF unittests/ADT/CMakeFiles/ADTTests.dir/SequenceTest.cpp.o.d -o unittests/ADT/CMakeFiles/ADTTests.dir/SequenceTest.cpp.o -c /usr/local/google/home/kubak/llvm/llvm-project/llvm/unittests/ADT/SequenceTest.cpp
In file included from /usr/local/google/home/kubak/llvm/llvm-project/llvm/unittests/ADT/SequenceTest.cpp:9:
In file included from /usr/local/google/home/kubak/llvm/llvm-project/llvm/include/llvm/ADT/Sequence.h:84:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/iterator:65:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/stream_iterator.h:35:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/debug/debug.h:133:
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/debug/functions.h:110:44: error: no matching function for call to '__addressof'
return __foreign_iterator_aux4(__it, std::__addressof(*__other));
^~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/debug/functions.h:164:14: note: in instantiation of function template specialization '__gnu_debug::__foreign_iterator_aux3<__gnu_cxx::__normal_iterator<const int *, std::__cxx1998::vector<int>>, std::vector<int>, std::random_access_iterator_tag, llvm::detail::SafeIntIterator<int, false>>' requested here
return __foreign_iterator_aux3(__it, __other, __other_end, __tag());
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/debug/functions.h:186:5: note: in instantiation of function template specialization '__gnu_debug::__foreign_iterator_aux2<__gnu_cxx::__normal_iterator<const int *, std::__cxx1998::vector<int>>, std::vector<int>, std::random_access_iterator_tag, llvm::detail::SafeIntIterator<int, false>>' requested here
|| __foreign_iterator_aux2(__it, std::__miter_base(__other),
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/debug/functions.h:198:14: note: in instantiation of function template specialization '__gnu_debug::__foreign_iterator_aux<__gnu_cxx::__normal_iterator<const int *, std::__cxx1998::vector<int>>, std::vector<int>, std::random_access_iterator_tag, llvm::detail::SafeIntIterator<int, false>>' requested here
return __foreign_iterator_aux(__it, __other, __other_end, _Integral());
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/debug/vector:626:4: note: in instantiation of function template specialization '__gnu_debug::__foreign_iterator<__gnu_cxx::__normal_iterator<const int *, std::__cxx1998::vector<int>>, std::vector<int>, std::random_access_iterator_tag, llvm::detail::SafeIntIterator<int, false>>' requested here
__glibcxx_check_insert_range(__position, __first, __last, __dist);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/debug/macros.h:183:36: note: expanded from macro '__glibcxx_check_insert_range'
_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__foreign_iterator(_Position,_First,_Last),\
^
/usr/local/google/home/kubak/llvm/llvm-project/llvm/unittests/ADT/SequenceTest.cpp:303:8: note: in instantiation of function template specialization 'std::vector<int>::insert<llvm::detail::SafeIntIterator<int, false>, void>' requested here
vals.insert(vals.end(), begin, end);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/move.h:49:5: note: candidate function [with _Tp = int] not viable: expects an lvalue for 1st argument
__addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
^
1 error generated.
[2/3] Building CXX object unittests/ADT/CMakeFiles/ADTTests.dir/STLExtrasTest.cpp.o
ninja: build stopped: subcommand failed.
```
This seems to fail deep in libc++'s `function.h` debug code. Just before the failure, it determines that vector is a contiguous sequence and that what we insert should be an lvalue reference:
```
using __lvalref = std::is_lvalue_reference<
typename std::iterator_traits<_InputIterator>::reference>;
using __contiguous = _Is_contiguous_sequence<_Sequence>;
using __tag = std::__conditional_t<__lvalref::value, __contiguous,
std::__false_type>;
```
`__tag` evaluates to `std::true_type`. It then tries to take an address of the dereferenced `SafeIntIterator` and fails:
```c++
return __foreign_iterator_aux4(__it, std::__addressof(*__other));
```
I think this is because `SafeIntIterator` advertises the reference type as `int &` but `operator*` returns a `value_type`:
```c++
template <typename T, bool IsReverse> struct SafeIntIterator {
using iterator_category = std::random_access_iterator_tag;
using value_type = T;
using difference_type = intmax_t;
using pointer = T *;
using reference = T &;
// Dereference
value_type operator*() const { return SI.to<T>(); }
...
// In SafeInt::
// Convert to integral, asserts if Value cannot be represented as Integral.
template <typename Integral,
std::enable_if_t<std::is_integral<Integral>::value, bool> = 0>
Integral to() const {
if (!canTypeFitValue<Integral>(Value))
assertOutOfBounds();
return static_cast<Integral>(Value);
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzkWl1z27jO_jXMDUceWfLnRS4c2d71e5Imk7hNz5WGFiGZG4nUISknORfvbz8D6sOKk3R3u223M-vxyBYJggD4AAREMWNEJgHOyfiCjJdnrLJ7pc8fqj3TZzvFn8-vtciEZHn-TDWUSlvgdPdMycj_jT2ninEqJN1bWxoSLkiwJsFaw0HAoxnk-aEYKJ2RYL0cjkajwCdBOBpORuE0HBB_SfxFfd0YlTNkrKHUipJgljBJd0AZ58CpVZRM_Dv4TwUygS0YO0jKkkx8Esxx0prTxK-_CQku8Otat6u7LQlm_bEkiOgtzkOCOSXThpAay5FXuDhAYpUmYSSkJeGKHlhuKAmXSDvEwQFeQjJdkrAdTDlYJvKawR1LYSPtxoJmR05BRFOWG0CWO8iEJMFs5BT4SiYgOQlmkxcsUNaBkAa0JcHM3dVkSBVE7cRRPbg_9-rzzSraxttfF9tmJJKtcihAWrPQQIJZX_sgoiO8jB3nIyc0y8v16C90pGQqskoDRWzQR2H3uLTeMrpa_GsVX3zcXC7j7b9vViRcLmFXZdRbXl5-uopXHxYXl6sYpfxwt_m0iqNfV9G_7ki4HNJ2dPT5cxxdX91sLle3JFwmOZNZjQVvODpSvaLxhiMy8Qcv5SxKkQNNVFEwicBAMaWQvzG6WG4RRuaVajiEWaEkBa1xyU6RWd-uF5vL1RJZVlJY61gF68VyS4J1dMUeYC1yaJrcRAMuNAnWp_gfKFozTBKW7IGSYF0ZJNzhEq9fqX9qO-otf0H3iH9d3MW32-2GhEufest4ubr4-Av--eVyc4FGXdzdrW63m-sPd_3WI9mHj_Hd9cfbaIV32Htz0y7Yy6Hx3XaJ9v9wt1182MZXi-j2utexvr69WrxuvtxcbY6tm07PXCUsJ8E6UyrLgQTrvSrw56HasQfszw8FmqMSOfc4ogmHvrT5V_DDH6_U6jdI7LH1r_N9KaeQSV5x-GbyfTN-di8090qm7XNP7Y5Nc_OjpitU8tCfLr3ZRNRLpfIMFExakXhCWtClMsK5ppcehBE7kQv77AmZCwnG2wvOQVLvvnHcJWcWPCsK6LVVMquY5sA9dmAiZw0PCY_Uu2d5jqRPVjPq3UvlVbIy4ARnBVjQ1Lt_1MKCZ6wWMjPUu0-Ysd5_KoYjC2GMkJmXCsi5J6SwguXiv6AN9UrgTpOaca5k5i7Iofbv-cxLVFEy6zkBUHVBvXtRlLlIhPVSlud2r1WV7XGQOoAG7plHYZO9xyFlVW5r5lLBUwKl9exzCa5JegehbcVyj1uFWnDARfbe6DFVloGxHvLXAlfjvlbWS5Q8gDbO_qhqDoxju5AcpK1jpnefWMa9gj3vwKukqcom2fBSLlgmlbEiMV6icpwso7XAB6YF4yLxCpZoZerGTFbef0Gf9npMZ5XbzmqE1KoKJZt7ba2gXmbKXFiPPzKd1uxe6-VyhWVj_eGUeldL6l1t_3pA967Wf5nJgFNPfQNREvpdIuMbszVJoKQp7rmNL3OaalX8OBnCxTGX_J6iNDyPDS_lGexJuJiN_qgo9V4_GCA7sUOZkoQE66fZJJ6MvFzI6gndgQTrYdASnlyOArWZc0MsutxzMRn_DALthFtAYzWwIm7FcxYLfwoB283b_Tq5hmF4zAN_pAhpJRMX22oxhj4JFyOEVZecUqlowWyyFzKjLTlNlaYJ7mZYdAXTOGacazBGpSSYtsUCfjTYSksax6nSIDLZrUfMqqcRCWZxLFzB0hVWL3jNSLCIY2X3oE8qCErGq_9_-fn77TdB0w1Htdks4K-QVEhjcWuudzCVHs1ooSixpKWmhMRt5TWNM2kmq7iep7HLWyYMSRjVpMnTU0solS5YHh89M0qUNJYKaSkJFifmTp6ehvP57M2yFr996tPufp9mkqsiZkkCxhyFtCxDMhfGHN2fql_dJFOqMe4Z3Of3oOEPAyzsAayDUfc3duUt3joZZ28g7O-H1GxCwsX4ByIq-KcjilIyjcg0egdTwdtBq0CaeMcMuP5jyIp-JjS5RfmhAeqfjqYvxqc_Fp420kKmMZf8SUJUa-XFJMDo9KPg9E-HEn7iOMvFLnl6ipM9JA9x_RQ31kxmdeBpH2HUQEqFNg28ctb-4wL__e0oqmvxZpfD_Dec9IEETyWTXWLuiBucfMEATe758ulj_Gl1u1n_25nn90EWzOKbow3jdWPB-JLVVgsiMn4_pn__-jP00Vazb-Fz72LdNTYHBGH0tXgOInpQgn8R1199FPFjMdvUlIU61KX3aH6alSVMcsHRzp3lyfjCHV3E29KdDKF9xkscQQ-C7fIW5pBYQ5mk-YHlFbjaamgsbZ9DHUPAy9Io3pYkmNA4xjyDdpD_cL36HK1utsdhnamGdVVHM5C4aMDb04zxBSoZonQXlcg51nrR589U7RCgf_Yp0fZy9WQ1M8fHRPU07mAEdXbPsKmxqizBnZqYatecodCUifwo2FunQ9u9MNQAFAarT6SnHKBEL8DI0C7c1FAy8dvFGOzJxKfO82miOAzo_1XG0h2g_1O7B8eo0oBYE5ZysKALIcFQu2eW1h5ChaGMJkpakVWqQjFq_6QouiN8dBegNaap2asq5-6QsltgDSloHPXe2U8d6iuDyxDHOEpD6iDUeawwcc0t7nGLWjPN7XMJkhXQG9BtUpohmMMo3siy6vlv4_Y9fqveyV9fop4BUKh4Y3pNcWsTnOKu-_8eL8uyl5o59tzFX5bH1m36jQmaYIVq1zvZcdYuzyb-vP_t83WBKUbT9MV5E2Nk4tdV4cSngBMyC6Y5Ye44Wl017Cb-gG4swkhSq0VNatmDW_XGZzEoI844dBbm7sD6JI5OfNr6gfmdY-vv_IjlTctsqN0L-YBXg-6wg4RVBt7ThB9AW2GcG_WQT93JAXMuWqdqEyTfVRZbVNnuxShDoyB6Hpn4Negbq_-Ofbqtj4RR5xFbt60oldONuYUD6Pqc3FhdJZae6NA7-W8Q2xk3YRYypZ9fovcLmWF4wumoiWOxfUXARdqY60glpC3YE7rFCXGp3AlWzcqlvqcUR-O3NJMeTYeo-uUMujzCtLdXtwL3V8jt1bROu8n0osXj3WZgFQmjrdv_ZzWw6PHg310Hg0G3i-OsG9muQG3OTrq6O3InRBa9S3RFUUSZwVhrqEjpJxdhEyZxl92Be1UEDEjMO5ihbSk1aBm_CZFjwRWd5t_0uNQgcQ-PReqCVD8yd7KFUceqDa9d9EIIIvBwMXzsbmZqR1CrTk17FEak1HUOEya3zyWshXWan8wYzOrW2q97qtQWu67sdXqhKslNt0INVbOIxjIrkjjB3Pdd1j0QvXqt44yfh3weztkZnA8n0-l0OvLHo7P9OU_ms4D5s4RzPh8Gs3A25Hw02iUpzCepPzsT54EfhH7oB8NJ4I9Hg3A2n6azYBoE83A2nQZk5EPBRN69QHQmjKngfDIcBsFZznaQG_fCUhBIeKSukwQBGS_P9LlLwHdVZsjIzwUmLx0XK2zu3nTCVGe8JOOLbhcbL18FCBenEZBJ8zIIpnyvU5E68-iexpxVOj9_-TpUJuy-2g0SVbxbJjgVMONyKv4vAAD___rkyLc">