Message ID | 20180814135517.GA5649@redhat.com |
---|---|
State | New |
Headers | show |
Series | Simplify overflow checks in duration literals | expand |
On Tue, Aug 14, 2018 at 02:55:17PM +0100, Jonathan Wakely wrote: > * include/std/chrono (__check_overflow): Simplify definition. > (_Checked_integral_constant): Remove. > > Tested x86_64-linux, committed to trunk. > > > commit c0dec9d05de4695136694f78f2f76e3c9f15b3f1 > Author: Jonathan Wakely <jwakely@redhat.com> > Date: Tue Aug 14 14:33:38 2018 +0100 > > Simplify overflow checks in duration literals > > * include/std/chrono (__check_overflow): Simplify definition. > (_Checked_integral_constant): Remove. > > diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono > index da03fdccce4..871c896144a 100644 > --- a/libstdc++-v3/include/std/chrono > +++ b/libstdc++-v3/include/std/chrono > @@ -900,24 +900,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > { > #pragma GCC diagnostic push > #pragma GCC diagnostic ignored "-Wliteral-suffix" > - template<typename _Rep, unsigned long long _Val> > - 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"); > - }; > - > 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. Note that I fixed 57891 yesterday. Or is this either 65043 or 78244? > - using _CheckedVal = _Checked_integral_constant<_Rep, _Val::value>; > - return _Dur{_CheckedVal::value}; > + constexpr typename _Dur::rep __repval = _Val::value; > + static_assert(__repval >= 0 && __repval == _Val::value, > + "literal value cannot be represented by duration type"); > + return _Dur(__repval); > } > > constexpr chrono::duration<long double, ratio<3600,1>> Marek
On 14/08/18 09:59 -0400, Marek Polacek wrote: >On Tue, Aug 14, 2018 at 02:55:17PM +0100, Jonathan Wakely wrote: >> * include/std/chrono (__check_overflow): Simplify definition. >> (_Checked_integral_constant): Remove. >> >> Tested x86_64-linux, committed to trunk. >> >> > >> commit c0dec9d05de4695136694f78f2f76e3c9f15b3f1 >> Author: Jonathan Wakely <jwakely@redhat.com> >> Date: Tue Aug 14 14:33:38 2018 +0100 >> >> Simplify overflow checks in duration literals >> >> * include/std/chrono (__check_overflow): Simplify definition. >> (_Checked_integral_constant): Remove. >> >> diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono >> index da03fdccce4..871c896144a 100644 >> --- a/libstdc++-v3/include/std/chrono >> +++ b/libstdc++-v3/include/std/chrono >> @@ -900,24 +900,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION >> { >> #pragma GCC diagnostic push >> #pragma GCC diagnostic ignored "-Wliteral-suffix" >> - template<typename _Rep, unsigned long long _Val> >> - 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"); >> - }; >> - >> 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. > >Note that I fixed 57891 yesterday. Or is this either 65043 or 78244? Yes, thanks for that! That was what made me revisit the TODO. But using integral_constant there doesn't produce the required error, because it's in a system header. The standard requires it to be ill-formed, so I can't rely on the narrowing diagnostic :-( But I realised it could be simplified anyway (and that could have been done years ago, without waiting for the fixes to narrowing in template arguments).
diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono index da03fdccce4..871c896144a 100644 --- a/libstdc++-v3/include/std/chrono +++ b/libstdc++-v3/include/std/chrono @@ -900,24 +900,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wliteral-suffix" - template<typename _Rep, unsigned long long _Val> - 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"); - }; - 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 typename _Dur::rep __repval = _Val::value; + static_assert(__repval >= 0 && __repval == _Val::value, + "literal value cannot be represented by duration type"); + return _Dur(__repval); } constexpr chrono::duration<long double, ratio<3600,1>>