From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21341 invoked by alias); 14 May 2014 13:39:19 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 21315 invoked by uid 89); 14 May 2014 13:39:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.2 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_NONE,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: vms173003pub.verizon.net Received: from vms173003pub.verizon.net (HELO vms173003pub.verizon.net) (206.46.173.3) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 14 May 2014 13:39:16 +0000 Received: from [192.168.1.3] ([unknown] [96.244.82.171]) by vms173003.mailsrvcs.net (Sun Java(tm) System Messaging Server 7u2-7.02 32bit (built Apr 16 2009)) with ESMTPA id <0N5K002A0GKR6XA0@vms173003.mailsrvcs.net>; Wed, 14 May 2014 08:38:52 -0500 (CDT) Message-id: <537371EF.9080901@verizon.net> Date: Wed, 14 May 2014 13:39:00 -0000 From: Ed Smith-Rowland <3dw4rd@verizon.net> User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.5.0 MIME-version: 1.0 To: gcc-patches , "libstdc++@gcc.gnu.org" Subject: [PATCH, libstdc++/61166] overflow when parse number in std::duration operator"" Content-type: multipart/mixed; boundary=------------010606060009020707020509 X-SW-Source: 2014-05/txt/msg01083.txt.bz2 This is a multi-part message in MIME format. --------------010606060009020707020509 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 189 Make the machinery in bits/parse_number.h unsigned long long. I had actually noticed this a while back but we were in stage 4. Then I forgot.. :-/ Built and tested on x84_64-linux. OK? --------------010606060009020707020509 Content-Type: text/plain; charset=UTF-8; name="CL_pr61166" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="CL_pr61166" Content-length: 253 2014-05-14 Ed Smith-Rowland <3dw4rd@verizon.net> libstdc++/61166 overflow when parse number in std::duration operator"" * include/bits/parse_numbers.h: Make the machinery unsigned long long. * testsuite/20_util/duration/literals/pr61166.cc: New. --------------010606060009020707020509 Content-Type: text/plain; charset=UTF-8; name="patch_pr61166" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="patch_pr61166" Content-length: 13921 Index: include/bits/parse_numbers.h =================================================================== --- include/bits/parse_numbers.h (revision 210315) +++ include/bits/parse_numbers.h (working copy) @@ -27,8 +27,8 @@ * Do not attempt to use it directly. @headername{chrono} */ -#ifndef _PARSE_NUMBERS_H -#define _PARSE_NUMBERS_H 1 +#ifndef _GLIBCXX_PARSE_NUMBERS_H +#define _GLIBCXX_PARSE_NUMBERS_H 1 #pragma GCC system_header @@ -36,262 +36,278 @@ #if __cplusplus > 201103L +#include + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION -namespace __parse_int { +namespace __parse_int +{ - template + template struct _Digit; - template + template struct _Digit<_Base, '0'> { static constexpr bool valid{true}; - static constexpr unsigned value{0}; + static constexpr unsigned long long value{0}; }; - template + template struct _Digit<_Base, '1'> { static constexpr bool valid{true}; - static constexpr unsigned value{1}; + static constexpr unsigned long long value{1}; }; - template + template struct _Digit<_Base, '2'> { static_assert(_Base > 2, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{2}; + static constexpr unsigned long long value{2}; }; - template + template struct _Digit<_Base, '3'> { static_assert(_Base > 3, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{3}; + static constexpr unsigned long long value{3}; }; - template + template struct _Digit<_Base, '4'> { static_assert(_Base > 4, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{4}; + static constexpr unsigned long long value{4}; }; - template + template struct _Digit<_Base, '5'> { static_assert(_Base > 5, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{5}; + static constexpr unsigned long long value{5}; }; - template + template struct _Digit<_Base, '6'> { static_assert(_Base > 6, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{6}; + static constexpr unsigned long long value{6}; }; - template + template struct _Digit<_Base, '7'> { static_assert(_Base > 7, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{7}; + static constexpr unsigned long long value{7}; }; - template + template struct _Digit<_Base, '8'> { static_assert(_Base > 8, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{8}; + static constexpr unsigned long long value{8}; }; - template + template struct _Digit<_Base, '9'> { static_assert(_Base > 9, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{9}; + static constexpr unsigned long long value{9}; }; - template + template struct _Digit<_Base, 'a'> { static_assert(_Base > 0xa, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{0xa}; + static constexpr unsigned long long value{0xa}; }; - template + template struct _Digit<_Base, 'A'> { static_assert(_Base > 0xa, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{0xa}; + static constexpr unsigned long long value{0xa}; }; - template + template struct _Digit<_Base, 'b'> { static_assert(_Base > 0xb, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{0xb}; + static constexpr unsigned long long value{0xb}; }; - template + template struct _Digit<_Base, 'B'> { static_assert(_Base > 0xb, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{0xb}; + static constexpr unsigned long long value{0xb}; }; - template + template struct _Digit<_Base, 'c'> { static_assert(_Base > 0xc, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{0xc}; + static constexpr unsigned long long value{0xc}; }; - template + template struct _Digit<_Base, 'C'> { static_assert(_Base > 0xc, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{0xc}; + static constexpr unsigned long long value{0xc}; }; - template + template struct _Digit<_Base, 'd'> { static_assert(_Base > 0xd, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{0xd}; + static constexpr unsigned long long value{0xd}; }; - template + template struct _Digit<_Base, 'D'> { static_assert(_Base > 0xd, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{0xd}; + static constexpr unsigned long long value{0xd}; }; - template + template struct _Digit<_Base, 'e'> { static_assert(_Base > 0xe, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{0xe}; + static constexpr unsigned long long value{0xe}; }; - template + template struct _Digit<_Base, 'E'> { static_assert(_Base > 0xe, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{0xe}; + static constexpr unsigned long long value{0xe}; }; - template + template struct _Digit<_Base, 'f'> { static_assert(_Base > 0xf, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{0xf}; + static constexpr unsigned long long value{0xf}; }; - template + template struct _Digit<_Base, 'F'> { static_assert(_Base > 0xf, "invalid digit"); static constexpr bool valid{true}; - static constexpr unsigned value{0xf}; + static constexpr unsigned long long value{0xf}; }; + // Radix + template + struct _Digit<_Base, '.'> + { + static constexpr bool valid{false}; + static constexpr unsigned long long value{0}; + }; + // Digit separator - template + template struct _Digit<_Base, '\''> { static constexpr bool valid{false}; - static constexpr unsigned value{0}; + static constexpr unsigned long long value{0}; }; //------------------------------------------------------------------------------ - template + template struct _Digits_help { - static constexpr unsigned + static constexpr unsigned long long value{_Digit<_Base, _Dig>::valid ? 1U + _Digits_help<_Base, _Digs...>::value : _Digits_help<_Base, _Digs...>::value}; }; - template + template struct _Digits_help<_Base, _Dig> { - static constexpr unsigned value{_Digit<_Base, _Dig>::valid ? 1U : 0U}; + static constexpr unsigned long long + value{_Digit<_Base, _Dig>::valid ? 1U : 0U}; }; - template + template struct _Digits { - static constexpr unsigned value{_Digits_help<_Base, _Digs...>::value}; + static constexpr unsigned long long + value{_Digits_help<_Base, _Digs...>::value}; }; - template + template struct _Digits<_Base> { - static constexpr unsigned value{0U}; + static constexpr unsigned long long value{0U}; }; //------------------------------------------------------------------------------ - template + template struct _Power_help { - static constexpr unsigned - value{_Digit<_Base, _Dig>::valid ? - _Base * _Power_help<_Base, _Digs...>::value : - _Power_help<_Base, _Digs...>::value}; + static constexpr unsigned long long + value{_Digit<_Base, _Dig>::valid + ? _Base * _Power_help<_Base, _Digs...>::value + : _Power_help<_Base, _Digs...>::value}; }; - template + template struct _Power_help<_Base, _Dig> { - static constexpr unsigned value{_Digit<_Base, _Dig>::valid ? 1U : 0U}; + static constexpr unsigned long long + value{_Digit<_Base, _Dig>::valid ? 1ULL : 0ULL}; }; - template + template struct _Power { - static constexpr unsigned value{_Power_help<_Base, _Digs...>::value}; + static constexpr unsigned long long + value{_Power_help<_Base, _Digs...>::value}; }; - template + template struct _Power<_Base> { - static constexpr unsigned value{0U}; + static constexpr unsigned long long value{0ULL}; }; //------------------------------------------------------------------------------ - template + template struct _Number_help { - static constexpr unsigned + static constexpr unsigned long long value{_Digit<_Base, _Dig>::valid ? _Pow * _Digit<_Base, _Dig>::value + _Number_help<_Base, _Pow / _Base, _Digs...>::value : @@ -298,26 +314,26 @@ _Number_help<_Base, _Pow, _Digs...>::value}; }; - template + template struct _Number_help<_Base, _Pow, _Dig> { - //static_assert(_Pow == 1U, "power should be one"); - static constexpr unsigned - value{_Digit<_Base, _Dig>::valid ? _Digit<_Base, _Dig>::value : 0U}; + //static_assert(_Pow == 1ULL, "power should be one"); + static constexpr unsigned long long + value{_Digit<_Base, _Dig>::valid ? _Digit<_Base, _Dig>::value : 0ULL}; }; - template + template struct _Number { - static constexpr unsigned + static constexpr unsigned long long value{_Number_help<_Base, _Power<_Base, _Digs...>::value, _Digs...>::value}; }; - template + template struct _Number<_Base> { - static constexpr unsigned value{0U}; + static constexpr unsigned long long value{0ULL}; }; //------------------------------------------------------------------------------ @@ -371,7 +387,8 @@ } // namespace __parse_int -namespace __select_int { +namespace __select_int +{ template struct _Select_int_base; @@ -414,4 +431,4 @@ #endif // __cplusplus > 201103L -#endif // _PARSE_NUMBERS_H +#endif // _GLIBCXX_PARSE_NUMBERS_H Index: testsuite/20_util/duration/literals/pr61166.cc =================================================================== --- testsuite/20_util/duration/literals/pr61166.cc (revision 0) +++ testsuite/20_util/duration/literals/pr61166.cc (working copy) @@ -0,0 +1,37 @@ +// { dg-do run } +// { 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 +#include + +void +test03() +{ + using namespace std::literals::chrono_literals; + + // std::numeric_limits::max() == 4294967295 + VERIFY( (429496729510h).count() == 429496729510 ); +} + +int +main() +{ + test03(); +} --------------010606060009020707020509--