Commit cd1464db by Jonathan Wakely

parse_numbers.h (__parse_int::_Number_help): Check for overflow.

	* include/bits/parse_numbers.h (__parse_int::_Number_help): Check for
	overflow.
	* include/std/chrono (chrono_literals::__select_type::_Select_type):
	Remove.
	(chrono_literals::_Checked_integral_constant): Define.
	Simplify UDL operator templates and check for overflow.
	* testsuite/20_util/duration/literals/range.cc: New.

From-SVN: r210513
parent 3d840f7d
2014-05-15 Ed Smith-Rowland <3dw4rd@verizon.net> 2014-05-16 Jonathan Wakely <jwakely@redhat.com>
* include/bits/parse_numbers.h (__parse_int::_Number_help): Check for
overflow.
* include/std/chrono (chrono_literals::__select_type::_Select_type):
Remove.
(chrono_literals::_Checked_integral_constant): Define.
Simplify UDL operator templates and check for overflow.
* testsuite/20_util/duration/literals/range.cc: New.
2014-05-16 Ed Smith-Rowland <3dw4rd@verizon.net>
Jonathan Wakely <jwakely@redhat.com> Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/61166 PR libstdc++/61166
......
...@@ -193,6 +193,7 @@ namespace __parse_int ...@@ -193,6 +193,7 @@ namespace __parse_int
_Pow / (_Base * __valid_digit::value), _Pow / (_Base * __valid_digit::value),
_Digs...>; _Digs...>;
using type = __ull_constant<_Pow * __digit::value + __next::type::value>; using type = __ull_constant<_Pow * __digit::value + __next::type::value>;
static_assert((type::value / _Pow) == __digit::value, "overflow");
}; };
template<unsigned _Base, unsigned long long _Pow, char _Dig> template<unsigned _Base, unsigned long long _Pow, char _Dig>
......
...@@ -787,117 +787,79 @@ _GLIBCXX_END_NAMESPACE_VERSION ...@@ -787,117 +787,79 @@ _GLIBCXX_END_NAMESPACE_VERSION
inline namespace chrono_literals inline namespace chrono_literals
{ {
namespace __select_type template<typename _Rep, unsigned long long _Val>
{ struct _Checked_integral_constant
: integral_constant<_Rep, static_cast<_Rep>(_Val)>
using namespace __parse_int; {
static_assert(_Checked_integral_constant::value > 0
template<unsigned long long _Val, typename _Dur> && _Checked_integral_constant::value == _Val,
struct _Select_type "literal value cannot be represented by duration type");
: conditional< };
_Val <= static_cast<unsigned long long>
(numeric_limits<typename _Dur::rep>::max()),
_Dur, void>
{
static constexpr typename _Select_type::type
value{static_cast<typename _Select_type::type>(_Val)};
};
template<unsigned long long _Val, typename _Dur>
constexpr typename _Select_type<_Val, _Dur>::type
_Select_type<_Val, _Dur>::value;
} // __select_type template<typename _Dur, char... _Digits>
constexpr _Dur __check_overflow()
{
using _Val = __parse_int::_Parse_int<_Digits...>;
using _Rep = typename _Dur::rep;
// TODO: should be simply integral_constant<_Rep, _Val::value>
// but GCC doesn't reject narrowing conversions to _Rep.
using _CheckedVal = _Checked_integral_constant<_Rep, _Val::value>;
return _Dur{_CheckedVal::value};
}
constexpr chrono::duration<long double, ratio<3600,1>> constexpr chrono::duration<long double, ratio<3600,1>>
operator""h(long double __hours) operator""h(long double __hours)
{ return chrono::duration<long double, ratio<3600,1>>{__hours}; } { return chrono::duration<long double, ratio<3600,1>>{__hours}; }
template <char... _Digits> template <char... _Digits>
constexpr typename constexpr chrono::hours
__select_type::_Select_type<__select_int::_Select_int<_Digits...>::value,
chrono::hours>::type
operator""h() operator""h()
{ { return __check_overflow<chrono::hours, _Digits...>(); }
return __select_type::_Select_type<
__select_int::_Select_int<_Digits...>::value,
chrono::hours>::value;
}
constexpr chrono::duration<long double, ratio<60,1>> constexpr chrono::duration<long double, ratio<60,1>>
operator""min(long double __mins) operator""min(long double __mins)
{ return chrono::duration<long double, ratio<60,1>>{__mins}; } { return chrono::duration<long double, ratio<60,1>>{__mins}; }
template <char... _Digits> template <char... _Digits>
constexpr typename constexpr chrono::minutes
__select_type::_Select_type<__select_int::_Select_int<_Digits...>::value,
chrono::minutes>::type
operator""min() operator""min()
{ { return __check_overflow<chrono::minutes, _Digits...>(); }
return __select_type::_Select_type<
__select_int::_Select_int<_Digits...>::value,
chrono::minutes>::value;
}
constexpr chrono::duration<long double> constexpr chrono::duration<long double>
operator""s(long double __secs) operator""s(long double __secs)
{ return chrono::duration<long double>{__secs}; } { return chrono::duration<long double>{__secs}; }
template <char... _Digits> template <char... _Digits>
constexpr typename constexpr chrono::seconds
__select_type::_Select_type<__select_int::_Select_int<_Digits...>::value,
chrono::seconds>::type
operator""s() operator""s()
{ { return __check_overflow<chrono::seconds, _Digits...>(); }
return __select_type::_Select_type<
__select_int::_Select_int<_Digits...>::value,
chrono::seconds>::value;
}
constexpr chrono::duration<long double, milli> constexpr chrono::duration<long double, milli>
operator""ms(long double __msecs) operator""ms(long double __msecs)
{ return chrono::duration<long double, milli>{__msecs}; } { return chrono::duration<long double, milli>{__msecs}; }
template <char... _Digits> template <char... _Digits>
constexpr typename constexpr chrono::milliseconds
__select_type::_Select_type<__select_int::_Select_int<_Digits...>::value,
chrono::milliseconds>::type
operator""ms() operator""ms()
{ { return __check_overflow<chrono::milliseconds, _Digits...>(); }
return __select_type::_Select_type<
__select_int::_Select_int<_Digits...>::value,
chrono::milliseconds>::value;
}
constexpr chrono::duration<long double, micro> constexpr chrono::duration<long double, micro>
operator""us(long double __usecs) operator""us(long double __usecs)
{ return chrono::duration<long double, micro>{__usecs}; } { return chrono::duration<long double, micro>{__usecs}; }
template <char... _Digits> template <char... _Digits>
constexpr typename constexpr chrono::microseconds
__select_type::_Select_type<__select_int::_Select_int<_Digits...>::value,
chrono::microseconds>::type
operator""us() operator""us()
{ { return __check_overflow<chrono::microseconds, _Digits...>(); }
return __select_type::_Select_type<
__select_int::_Select_int<_Digits...>::value,
chrono::microseconds>::value;
}
constexpr chrono::duration<long double, nano> constexpr chrono::duration<long double, nano>
operator""ns(long double __nsecs) operator""ns(long double __nsecs)
{ return chrono::duration<long double, nano>{__nsecs}; } { return chrono::duration<long double, nano>{__nsecs}; }
template <char... _Digits> template <char... _Digits>
constexpr typename constexpr chrono::nanoseconds
__select_type::_Select_type<__select_int::_Select_int<_Digits...>::value,
chrono::nanoseconds>::type
operator""ns() operator""ns()
{ { return __check_overflow<chrono::nanoseconds, _Digits...>(); }
return __select_type::_Select_type<
__select_int::_Select_int<_Digits...>::value,
chrono::nanoseconds>::value;
}
} // inline namespace chrono_literals } // inline namespace chrono_literals
} // inline namespace literals } // inline namespace literals
......
// { dg-do compile }
// { dg-options "-std=gnu++1y" }
// Copyright (C) 2014 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/>.
#include <chrono>
void
test01()
{
using namespace std::literals::chrono_literals;
// std::numeric_limits<int64_t>::max() == 9223372036854775807;
auto h = 9223372036854775808h;
// { dg-error "cannot be represented" "" { target *-*-* } 794 }
}
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