commit 361c9b79e0b1c7f2435f5b0b369a139b216dee90 Author: Jonathan Wakely Date: Fri May 16 10:31:38 2014 +0100 * 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. diff --git a/libstdc++-v3/include/bits/parse_numbers.h b/libstdc++-v3/include/bits/parse_numbers.h index 0a42381a..a29d127 100644 --- a/libstdc++-v3/include/bits/parse_numbers.h +++ b/libstdc++-v3/include/bits/parse_numbers.h @@ -193,6 +193,7 @@ namespace __parse_int _Pow / (_Base * __valid_digit::value), _Digs...>; using type = __ull_constant<_Pow * __digit::value + __next::type::value>; + static_assert((type::value / _Pow) == __digit::value, "overflow"); }; template diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono index b114e02..39ad5e3 100644 --- a/libstdc++-v3/include/std/chrono +++ b/libstdc++-v3/include/std/chrono @@ -787,117 +787,79 @@ _GLIBCXX_END_NAMESPACE_VERSION inline namespace chrono_literals { - namespace __select_type - { - - using namespace __parse_int; - - template - struct _Select_type - : conditional< - _Val <= static_cast - (numeric_limits::max()), - _Dur, void> - { - static constexpr typename _Select_type::type - value{static_cast(_Val)}; - }; - - template - constexpr typename _Select_type<_Val, _Dur>::type - _Select_type<_Val, _Dur>::value; + template + struct _Checked_integral_constant + : integral_constant<_Rep, static_cast<_Rep>(_Val)> + { + static_assert(_Checked_integral_constant::value > 0 + && _Checked_integral_constant::value == _Val, + "literal value cannot be represented by duration type"); + }; - } // __select_type + template + 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> operator""h(long double __hours) { return chrono::duration>{__hours}; } template - constexpr typename - __select_type::_Select_type<__select_int::_Select_int<_Digits...>::value, - chrono::hours>::type + constexpr chrono::hours operator""h() - { - return __select_type::_Select_type< - __select_int::_Select_int<_Digits...>::value, - chrono::hours>::value; - } + { return __check_overflow(); } constexpr chrono::duration> operator""min(long double __mins) { return chrono::duration>{__mins}; } template - constexpr typename - __select_type::_Select_type<__select_int::_Select_int<_Digits...>::value, - chrono::minutes>::type + constexpr chrono::minutes operator""min() - { - return __select_type::_Select_type< - __select_int::_Select_int<_Digits...>::value, - chrono::minutes>::value; - } + { return __check_overflow(); } constexpr chrono::duration operator""s(long double __secs) { return chrono::duration{__secs}; } template - constexpr typename - __select_type::_Select_type<__select_int::_Select_int<_Digits...>::value, - chrono::seconds>::type + constexpr chrono::seconds operator""s() - { - return __select_type::_Select_type< - __select_int::_Select_int<_Digits...>::value, - chrono::seconds>::value; - } + { return __check_overflow(); } constexpr chrono::duration operator""ms(long double __msecs) { return chrono::duration{__msecs}; } template - constexpr typename - __select_type::_Select_type<__select_int::_Select_int<_Digits...>::value, - chrono::milliseconds>::type + constexpr chrono::milliseconds operator""ms() - { - return __select_type::_Select_type< - __select_int::_Select_int<_Digits...>::value, - chrono::milliseconds>::value; - } + { return __check_overflow(); } constexpr chrono::duration operator""us(long double __usecs) { return chrono::duration{__usecs}; } template - constexpr typename - __select_type::_Select_type<__select_int::_Select_int<_Digits...>::value, - chrono::microseconds>::type + constexpr chrono::microseconds operator""us() - { - return __select_type::_Select_type< - __select_int::_Select_int<_Digits...>::value, - chrono::microseconds>::value; - } + { return __check_overflow(); } constexpr chrono::duration operator""ns(long double __nsecs) { return chrono::duration{__nsecs}; } template - constexpr typename - __select_type::_Select_type<__select_int::_Select_int<_Digits...>::value, - chrono::nanoseconds>::type + constexpr chrono::nanoseconds operator""ns() - { - return __select_type::_Select_type< - __select_int::_Select_int<_Digits...>::value, - chrono::nanoseconds>::value; - } + { return __check_overflow(); } } // inline namespace chrono_literals } // inline namespace literals diff --git a/libstdc++-v3/testsuite/20_util/duration/literals/range.cc b/libstdc++-v3/testsuite/20_util/duration/literals/range.cc new file mode 100644 index 0000000..c005df6 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/duration/literals/range.cc @@ -0,0 +1,31 @@ +// { 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 +// . + +#include + +void +test01() +{ + using namespace std::literals::chrono_literals; + + // std::numeric_limits::max() == 9223372036854775807; + auto h = 9223372036854775808h; + // { dg-error "cannot be represented" "" { target *-*-* } 794 } +}