From f847e92fd76687d64bd43600d220978921be951c Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Tue, 26 Oct 2021 14:37:21 -0700 Subject: [PATCH] Address AlexG's other potential occurrences --- stl/inc/ranges | 12 +++++++++ .../P0896R4_ranges_alg_find_end/test.cpp | 21 +++++++++++++++ .../tests/P0896R4_ranges_alg_search/test.cpp | 20 ++++++++++++++ .../tests/P0896R4_ranges_alg_sort/test.cpp | 20 +++----------- tests/std/tests/P0896R4_views_split/test.cpp | 26 +++++++++++++++++++ 5 files changed, 83 insertions(+), 16 deletions(-) diff --git a/stl/inc/ranges b/stl/inc/ranges index 11a4d3e51f..4336da3fd2 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -3777,7 +3777,13 @@ namespace ranges { return *this; } +#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-1559808 auto [_Begin, _End] = _RANGES search(subrange{_Current, _Last}, _Parent->_Pattern); +#else // ^^^ no workaround / workaround vvv + auto _Match = _RANGES search(subrange{_Current, _Last}, _Parent->_Pattern); + auto _Begin = _Match.begin(); + auto _End = _Match.end(); +#endif // TRANSITION, DevCom-1559808 if (_Begin != _Last && _RANGES empty(_Parent->_Pattern)) { ++_Begin; ++_End; @@ -3823,7 +3829,13 @@ namespace ranges { constexpr subrange> _Find_next(iterator_t<_Vw> _It) { const auto _Last = _RANGES end(_Range); +#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevCom-1559808 auto [_Begin, _End] = _RANGES search(subrange{_It, _Last}, _Pattern); +#else // ^^^ no workaround / workaround vvv + auto _Match = _RANGES search(subrange{_It, _Last}, _Pattern); + auto _Begin = _Match.begin(); + auto _End = _Match.end(); +#endif // TRANSITION, DevCom-1559808 if (_Begin != _Last && _RANGES empty(_Pattern)) { ++_Begin; ++_End; diff --git a/tests/std/tests/P0896R4_ranges_alg_find_end/test.cpp b/tests/std/tests/P0896R4_ranges_alg_find_end/test.cpp index feb9cd3179..87a0f93a87 100644 --- a/tests/std/tests/P0896R4_ranges_alg_find_end/test.cpp +++ b/tests/std/tests/P0896R4_ranges_alg_find_end/test.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -71,9 +72,29 @@ constexpr void smoke_test() { } } +constexpr void test_1559808() { + // Regression test for DevCom-1559808, an interaction between vector and the + // use of structured bindings in the constexpr evaluator. + + std::vector haystack(33, 42), needle(8, 42); // No particular significance to any numbers in this function + using size_type = std::vector::size_type; + + auto result = ranges::find_end(haystack, needle); + assert(static_cast(result.begin() - haystack.begin()) == haystack.size() - needle.size()); + assert(result.end() == haystack.end()); + + needle.assign(6, 1729); + result = ranges::find_end(haystack, needle); + assert(result.begin() == haystack.end()); + assert(result.end() == haystack.end()); +} + int main() { STATIC_ASSERT((smoke_test(), true)); smoke_test(); + + STATIC_ASSERT((test_1559808(), true)); + test_1559808(); } #ifndef _PREFAST_ // TRANSITION, GH-1030 diff --git a/tests/std/tests/P0896R4_ranges_alg_search/test.cpp b/tests/std/tests/P0896R4_ranges_alg_search/test.cpp index 09875c7199..9d768b70a6 100644 --- a/tests/std/tests/P0896R4_ranges_alg_search/test.cpp +++ b/tests/std/tests/P0896R4_ranges_alg_search/test.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -168,8 +169,27 @@ constexpr bool run_tests() { return true; } +constexpr void test_1559808() { + // Regression test for DevCom-1559808, an interaction between vector and the + // use of structured bindings in the constexpr evaluator. + + std::vector haystack(33, 42), needle(8, 42); // No particular significance to any numbers in this function + + auto result = ranges::search(haystack, needle); + assert(result.begin() == haystack.begin()); + assert(result.end() == haystack.begin() + ranges::ssize(needle)); + + needle.assign(6, 1729); + result = ranges::search(haystack, needle); + assert(result.begin() == haystack.end()); + assert(result.end() == haystack.end()); +} + int main() { STATIC_ASSERT(run_tests()); run_tests(); + + STATIC_ASSERT((test_1559808(), true)); + test_1559808(); } #endif // TEST_EVERYTHING diff --git a/tests/std/tests/P0896R4_ranges_alg_sort/test.cpp b/tests/std/tests/P0896R4_ranges_alg_sort/test.cpp index c66e743dc7..6c47457133 100644 --- a/tests/std/tests/P0896R4_ranges_alg_sort/test.cpp +++ b/tests/std/tests/P0896R4_ranges_alg_sort/test.cpp @@ -54,23 +54,11 @@ struct instantiator { constexpr void test_1559808() { // Regression test for DevCom-1559808, a bad interaction between constexpr vector and the use of structured bindings - // in the implemenation of ranges::sort. + // in the implementation of ranges::sort. - auto collatz = [](int n) { - vector vec = {n}; - while (n != 1) { - if (n % 2 == 0) { - n /= 2; - } else { - n = n * 3 + 1; - } - vec.push_back(n); - } - ranges::sort(vec); - return vec.back(); - }; - - assert(collatz(27) == 9232); + vector vec(33, 42); // NB: 33 > std::_ISORT_MAX + ranges::sort(vec); + assert(vec.back() == 42); } int main() { diff --git a/tests/std/tests/P0896R4_views_split/test.cpp b/tests/std/tests/P0896R4_views_split/test.cpp index de6d0e2450..18a067272d 100644 --- a/tests/std/tests/P0896R4_views_split/test.cpp +++ b/tests/std/tests/P0896R4_views_split/test.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include using namespace std; @@ -320,7 +321,32 @@ constexpr bool instantiation_test() { return true; } +constexpr bool test_1559808() { + // Regression test for DevCom-1559808, an interaction between vector and the + // use of structured bindings in the constexpr evaluator. + + vector letters{'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 't', 'e', 's', 't'}; + auto r = views::split(letters, ' '); + auto i = r.begin(); + assert(*(*i).begin() == 'T'); + ++i; + assert(*(*i).begin() == 'i'); + ++i; + assert(*(*i).begin() == 'a'); + ++i; + assert(*(*i).begin() == 't'); + ++i; + assert(i == r.end()); + + return true; +} + int main() { STATIC_ASSERT(instantiation_test()); instantiation_test(); + +#if defined(__clang__) || defined(__EDG__) // TRANSITION, DevDiv-1516290 + STATIC_ASSERT(test_1559808()); +#endif // TRANSITION, DevDiv-1516290 + test_1559808(); }