Bug 53080

Summary: tuple interface to std::array doesn't check bounds
Product: gcc Reporter: Akira Takahashi <faithandbrave>
Component: libstdc++Assignee: Paolo Carlini <paolo.carlini>
Status: RESOLVED FIXED    
Severity: normal CC: daniel.kruegler
Priority: P3    
Version: 4.7.0   
Target Milestone: 4.8.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2012-04-23 00:00:00

Description Akira Takahashi 2012-04-23 02:15:00 UTC
"23.3.2.9 Tuple interface to class template array" in N3337(C++ Specification Draft)

tuple_element<I, array<T, N> >::type
Requires: I < N. The program is ill-formed if I is out of bounds.

template <size_t I, class T, size_t N> T& get(array<T, N>& a) noexcept;
Requires: I < N. The program is ill-formed if I is out of bounds.

GCC 4.7.0 libstdc++ <array> header is no check bounds.
I think need static_assert to tuple_element and get().

Issue code is follow:

template<std::size_t _Int, typename _Tp, std::size_t _Nm>
struct tuple_element<_Int, array<_Tp, _Nm> >
  { typedef _Tp type; };

template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  constexpr _Tp&
  get(array<_Tp, _Nm>& __arr) noexcept
  { return __arr._M_instance[_Int]; }

template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  constexpr _Tp&&
  get(array<_Tp, _Nm>&& __arr) noexcept
  { return std::move(get<_Int>(__arr)); }

template<std::size_t _Int, typename _Tp, std::size_t _Nm>
  constexpr const _Tp&
  get(const array<_Tp, _Nm>& __arr) noexcept
  { return __arr._M_instance[_Int]; }
Comment 1 Jonathan Wakely 2012-04-23 08:35:41 UTC
Testcase:

#include <array>
int main()
{
  typedef std::tuple_element<1, std::array<int, 1>> type;
  std::array<int, 1> a;
  std::get<1>(a);
}
Comment 2 Paolo Carlini 2012-04-23 10:50:33 UTC
Ok.
Comment 3 paolo@gcc.gnu.org 2012-04-23 12:26:57 UTC
Author: paolo
Date: Mon Apr 23 12:26:43 2012
New Revision: 186702

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=186702
Log:
2012-04-23  Paolo Carlini  <paolo.carlini@oracle.com>

	PR libstdc++/53080
	* include/std/array (tuple_element, get): static_assert I < N.
	* testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc:
	New.
	* testsuite/23_containers/array/tuple_interface/get_neg.cc: Likewise.
	* testsuite/23_containers/array/tuple_interface/tuple_element.cc: Fix.

Added:
    trunk/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
    trunk/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/std/array
    trunk/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element.cc
Comment 4 Paolo Carlini 2012-04-23 12:27:44 UTC
Done.
Comment 5 Akira Takahashi 2012-04-23 12:32:13 UTC
(In reply to comment #4)
> Done.

Great thanks!