Commit 3c040fa4 by Jonathan Wakely Committed by Jonathan Wakely

libstdc++/72745 add static assertion for invalid tuple access

	PR libstdc++/72745
	* include/std/array (get): Use positive message for static assertions.
	* include/std/functional (_Safe_tuple_element_t): Fix indentation.
	* include/std/tuple (tuple_element<I, tuple<>>): Add partial
	specialization for invalid indices, with static assertion.
	* testsuite/20_util/tuple/element_access/get_neg.cc: New test.

From-SVN: r238924
parent f245e3a0
2016-07-31 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/72745
* include/std/array (get): Use positive message for static assertions.
* include/std/functional (_Safe_tuple_element_t): Fix indentation.
* include/std/tuple (tuple_element<I, tuple<>>): Add partial
specialization for invalid indices, with static assertion.
* testsuite/20_util/tuple/element_access/get_neg.cc: New test.
* testsuite/20_util/duration/requirements/typedefs_neg3.cc: Move
dg-error to relevant line.
* testsuite/20_util/headers/type_traits/types_std_c++0x_neg.cc:
......
......@@ -292,7 +292,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
constexpr _Tp&
get(array<_Tp, _Nm>& __arr) noexcept
{
static_assert(_Int < _Nm, "index is out of bounds");
static_assert(_Int < _Nm, "array index is within bounds");
return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
_S_ref(__arr._M_elems, _Int);
}
......@@ -301,7 +301,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
constexpr _Tp&&
get(array<_Tp, _Nm>&& __arr) noexcept
{
static_assert(_Int < _Nm, "index is out of bounds");
static_assert(_Int < _Nm, "array index is within bounds");
return std::move(_GLIBCXX_STD_C::get<_Int>(__arr));
}
......@@ -309,7 +309,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
constexpr const _Tp&
get(const array<_Tp, _Nm>& __arr) noexcept
{
static_assert(_Int < _Nm, "index is out of bounds");
static_assert(_Int < _Nm, "array index is within bounds");
return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
_S_ref(__arr._M_elems, _Int);
}
......
......@@ -758,10 +758,10 @@ _GLIBCXX_MEM_FN_TRAITS(&&, false_type, true_type)
// Like tuple_element_t but SFINAE-friendly.
template<std::size_t __i, typename _Tuple>
using _Safe_tuple_element_t
= typename enable_if<(__i < tuple_size<_Tuple>::value),
tuple_element<__i, _Tuple>>::type::type;
template<std::size_t __i, typename _Tuple>
using _Safe_tuple_element_t
= typename enable_if<(__i < tuple_size<_Tuple>::value),
tuple_element<__i, _Tuple>>::type::type;
/**
* Maps an argument to bind() into an actual argument to the bound
......
......@@ -1243,6 +1243,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
/// class tuple_size
template<typename... _Elements>
struct tuple_size<tuple<_Elements...>>
: public integral_constant<std::size_t, sizeof...(_Elements)> { };
#if __cplusplus > 201402L
template <typename _Tp>
constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
#endif
/**
* Recursive case for tuple_element: strip off the first element in
* the tuple and retrieve the (i-1)th element of the remaining tuple.
......@@ -1260,15 +1270,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef _Head type;
};
/// class tuple_size
template<typename... _Elements>
struct tuple_size<tuple<_Elements...>>
: public integral_constant<std::size_t, sizeof...(_Elements)> { };
#if __cplusplus > 201402L
template <typename _Tp>
constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
#endif
/**
* Error case for tuple_element: invalid index.
*/
template<size_t __i>
struct tuple_element<__i, tuple<>>
{
static_assert(__i < tuple_size<tuple<>>::value,
"tuple index is in range");
};
template<std::size_t __i, typename _Head, typename... _Tail>
constexpr _Head&
......
// 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 "-fno-show-column" }
// { dg-do compile { target c++14 } }
// { dg-error "in range" "" { target *-*-* } 1279 }
#include <tuple>
void
test01()
{
using test_type = std::tuple<>;
test_type t;
std::get<0>(t); // { dg-error "no match" }
std::get<0>(const_cast<const test_type&>(t)); // { dg-error "no match" }
std::get<0>(static_cast<test_type&&>(t)); // { dg-error "no match" }
std::get<5>(t); // { dg-error "no match" }
std::get<5>(const_cast<const test_type&>(t)); // { dg-error "no match" }
std::get<5>(static_cast<test_type&&>(t)); // { dg-error "no match" }
}
void
test02()
{
using test_type = std::tuple<int>;
test_type t;
std::get<1>(t); // { dg-error "no match" }
std::get<1>(const_cast<const test_type&>(t)); // { dg-error "no match" }
std::get<1>(static_cast<test_type&&>(t)); // { dg-error "no match" }
std::get<5>(t); // { dg-error "no match" }
std::get<5>(const_cast<const test_type&>(t)); // { dg-error "no match" }
std::get<5>(static_cast<test_type&&>(t)); // { dg-error "no match" }
}
void
test03()
{
using test_type = std::tuple<int, int, int, int>;
test_type t;
std::get<5>(t); // { dg-error "no match" }
std::get<5>(const_cast<const test_type&>(t)); // { dg-error "no match" }
std::get<5>(static_cast<test_type&&>(t)); // { dg-error "no match" }
std::get<6>(t); // { dg-error "no match" }
std::get<6>(const_cast<const test_type&>(t)); // { dg-error "no match" }
std::get<6>(static_cast<test_type&&>(t)); // { dg-error "no match" }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment