The std::min, std::max, and std::minmax overloads that take a std::initializer_list all require that the list is not empty. The attached patch adds debug mode checks for this.
Thanks, Eelis
Index: libstdc++-v3/include/debug/formatter.h =================================================================== --- libstdc++-v3/include/debug/formatter.h (revision 233636) +++ libstdc++-v3/include/debug/formatter.h (working copy) @@ -87,6 +87,8 @@ __msg_splice_bad, __msg_splice_other, __msg_splice_overlap, + // std::initializer_list checks + __msg_empty_init_list, // iterator checks __msg_init_singular, __msg_init_copy_singular, Index: libstdc++-v3/src/c++11/debug.cc =================================================================== --- libstdc++-v3/src/c++11/debug.cc (revision 233636) +++ libstdc++-v3/src/c++11/debug.cc (working copy) @@ -139,6 +139,8 @@ "attempt to splice an iterator from a different container", "splice destination %1.name;" " occurs within source range [%2.name;, %3.name;)", + // std::initializer_list checks + "%1;(): empty initializer_list", // iterator checks "attempt to initialize an iterator that will immediately become singular", "attempt to copy-construct an iterator from a singular iterator", Index: libstdc++-v3/include/debug/macros.h =================================================================== --- libstdc++-v3/include/debug/macros.h (revision 233636) +++ libstdc++-v3/include/debug/macros.h (working copy) @@ -69,6 +69,12 @@ ._M_iterator(_First, #_First) \ ._M_iterator(_Last, #_Last)) +// Verify that the initializer_list is non-empty. +#define __glibcxx_check_non_empty_init_list(_List) \ +_GLIBCXX_DEBUG_VERIFY(_List.size() != 0, \ + _M_message(__gnu_debug::__msg_empty_init_list) \ + ._M_string(__func__)) + /** Verify that we can insert into *this with the iterator _Position. * Insertion into a container at a specific position requires that * the iterator be nonsingular, either dereferenceable or past-the-end, Index: libstdc++-v3/include/debug/debug.h =================================================================== --- libstdc++-v3/include/debug/debug.h (revision 233636) +++ libstdc++-v3/include/debug/debug.h (working copy) @@ -62,6 +62,7 @@ # define __glibcxx_requires_cond(_Cond,_Msg) # define __glibcxx_requires_valid_range(_First,_Last) +# define __glibcxx_requires_non_empty_init_list(_List) # define __glibcxx_requires_sorted(_First,_Last) # define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) # define __glibcxx_requires_sorted_set(_First1,_Last1,_First2) @@ -99,6 +100,8 @@ # define __glibcxx_requires_cond(_Cond,_Msg) _GLIBCXX_DEBUG_VERIFY(_Cond,_Msg) # define __glibcxx_requires_valid_range(_First,_Last) \ __glibcxx_check_valid_range(_First,_Last) +# define __glibcxx_requires_non_empty_init_list(_List) \ + __glibcxx_check_non_empty_init_list(_List) # define __glibcxx_requires_non_empty_range(_First,_Last) \ __glibcxx_check_non_empty_range(_First,_Last) # define __glibcxx_requires_sorted(_First,_Last) \ Index: libstdc++-v3/include/bits/stl_algo.h =================================================================== --- libstdc++-v3/include/bits/stl_algo.h (revision 233636) +++ libstdc++-v3/include/bits/stl_algo.h (working copy) @@ -3452,25 +3452,37 @@ _GLIBCXX14_CONSTEXPR inline _Tp min(initializer_list<_Tp> __l) - { return *std::min_element(__l.begin(), __l.end()); } + { + __glibcxx_requires_non_empty_init_list(__l); + return *std::min_element(__l.begin(), __l.end()); + } template<typename _Tp, typename _Compare> _GLIBCXX14_CONSTEXPR inline _Tp min(initializer_list<_Tp> __l, _Compare __comp) - { return *std::min_element(__l.begin(), __l.end(), __comp); } + { + __glibcxx_requires_non_empty_init_list(__l); + return *std::min_element(__l.begin(), __l.end(), __comp); + } template<typename _Tp> _GLIBCXX14_CONSTEXPR inline _Tp max(initializer_list<_Tp> __l) - { return *std::max_element(__l.begin(), __l.end()); } + { + __glibcxx_requires_non_empty_init_list(__l); + return *std::max_element(__l.begin(), __l.end()); + } template<typename _Tp, typename _Compare> _GLIBCXX14_CONSTEXPR inline _Tp max(initializer_list<_Tp> __l, _Compare __comp) - { return *std::max_element(__l.begin(), __l.end(), __comp); } + { + __glibcxx_requires_non_empty_init_list(__l); + return *std::max_element(__l.begin(), __l.end(), __comp); + } template<typename _Tp> _GLIBCXX14_CONSTEXPR @@ -3477,6 +3489,7 @@ inline pair<_Tp, _Tp> minmax(initializer_list<_Tp> __l) { + __glibcxx_requires_non_empty_init_list(__l); pair<const _Tp*, const _Tp*> __p = std::minmax_element(__l.begin(), __l.end()); return std::make_pair(*__p.first, *__p.second); @@ -3487,6 +3500,7 @@ inline pair<_Tp, _Tp> minmax(initializer_list<_Tp> __l, _Compare __comp) { + __glibcxx_requires_non_empty_init_list(__l); pair<const _Tp*, const _Tp*> __p = std::minmax_element(__l.begin(), __l.end(), __comp); return std::make_pair(*__p.first, *__p.second); Index: libstdc++-v3/testsuite/25_algorithms/max/debug/empty_neg.cc =================================================================== --- libstdc++-v3/testsuite/25_algorithms/max/debug/empty_neg.cc (revision 0) +++ libstdc++-v3/testsuite/25_algorithms/max/debug/empty_neg.cc (working copy) @@ -0,0 +1,34 @@ +// Copyright (C) 2016 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#define _GLIBCXX_DEBUG + +#include <algorithm> + +void test01() +{ + std::max<int>({}); // error: empty initializer_list +} + +int main() +{ + test01(); + return 0; +} Index: libstdc++-v3/testsuite/25_algorithms/min/debug/empty_neg.cc =================================================================== --- libstdc++-v3/testsuite/25_algorithms/min/debug/empty_neg.cc (revision 0) +++ libstdc++-v3/testsuite/25_algorithms/min/debug/empty_neg.cc (working copy) @@ -0,0 +1,34 @@ +// Copyright (C) 2016 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#define _GLIBCXX_DEBUG + +#include <algorithm> + +void test01() +{ + std::min<int>({}); // error: empty initializer_list +} + +int main() +{ + test01(); + return 0; +} Index: libstdc++-v3/testsuite/25_algorithms/minmax/debug/empty_neg.cc =================================================================== --- libstdc++-v3/testsuite/25_algorithms/minmax/debug/empty_neg.cc (revision 0) +++ libstdc++-v3/testsuite/25_algorithms/minmax/debug/empty_neg.cc (working copy) @@ -0,0 +1,34 @@ +// Copyright (C) 2016 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. +// +// { dg-options "-std=gnu++11" } +// { dg-do run { xfail *-*-* } } + +#define _GLIBCXX_DEBUG + +#include <algorithm> + +void test01() +{ + std::minmax<int>({}); // error: empty initializer_list +} + +int main() +{ + test01(); + return 0; +}