diff mbox series

Simplify overflow checks in duration literals

Message ID 20180814135517.GA5649@redhat.com
State New
Headers show
Series Simplify overflow checks in duration literals | expand

Commit Message

Jonathan Wakely Aug. 14, 2018, 1:55 p.m. UTC
* 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.

Comments

Marek Polacek Aug. 14, 2018, 1:59 p.m. UTC | #1
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
Jonathan Wakely Aug. 14, 2018, 2:11 p.m. UTC | #2
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 mbox series

Patch

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>>