Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/813463/?format=api
{ "id": 813463, "url": "http://patchwork.ozlabs.org/api/patches/813463/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/20170913140903.GA8606@redhat.com/", "project": { "id": 17, "url": "http://patchwork.ozlabs.org/api/projects/17/?format=api", "name": "GNU Compiler Collection", "link_name": "gcc", "list_id": "gcc-patches.gcc.gnu.org", "list_email": "gcc-patches@gcc.gnu.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20170913140903.GA8606@redhat.com>", "list_archive_url": null, "date": "2017-09-13T14:09:03", "name": "PR libstdc++/81468 constrain std::chrono::time_point constructor", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "8139f545d6e3db7eef52b835eded5d7720fd0a6a", "submitter": { "id": 48004, "url": "http://patchwork.ozlabs.org/api/people/48004/?format=api", "name": "Jonathan Wakely", "email": "jwakely@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/20170913140903.GA8606@redhat.com/mbox/", "series": [ { "id": 2925, "url": "http://patchwork.ozlabs.org/api/series/2925/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=2925", "date": "2017-09-13T14:09:03", "name": "PR libstdc++/81468 constrain std::chrono::time_point constructor", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/2925/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/813463/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/813463/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<gcc-patches-return-462038-incoming=patchwork.ozlabs.org@gcc.gnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "mailing list gcc-patches@gcc.gnu.org" ], "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org\n\t(client-ip=209.132.180.131; helo=sourceware.org;\n\tenvelope-from=gcc-patches-return-462038-incoming=patchwork.ozlabs.org@gcc.gnu.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org\n\theader.b=\"ALrs41Qx\"; dkim-atps=neutral", "sourceware.org; auth=none", "ext-mx06.extmail.prod.ext.phx2.redhat.com;\n\tdmarc=none (p=none dis=none) header.from=redhat.com", "ext-mx06.extmail.prod.ext.phx2.redhat.com;\n\tspf=fail smtp.mailfrom=jwakely@redhat.com" ], "Received": [ "from sourceware.org (server1.sourceware.org [209.132.180.131])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xsk7L3WH4z9s78\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 14 Sep 2017 00:09:33 +1000 (AEST)", "(qmail 94890 invoked by alias); 13 Sep 2017 14:09:14 -0000", "(qmail 92958 invoked by uid 89); 13 Sep 2017 14:09:13 -0000", "from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by\n\tsourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP;\n\tWed, 13 Sep 2017 14:09:06 +0000", "from smtp.corp.redhat.com\n\t(int-mx04.intmail.prod.int.phx2.redhat.com\n\t[10.5.11.14])\t(using TLSv1.2 with cipher AECDH-AES256-SHA\n\t(256/256 bits))\t(No client certificate requested)\tby\n\tmx1.redhat.com (Postfix) with ESMTPS id F0BE3356DA;\n\tWed, 13 Sep 2017 14:09:04 +0000 (UTC)", "from localhost (unknown [10.33.36.37])\tby smtp.corp.redhat.com\n\t(Postfix) with ESMTP id 79F35612A7;\n\tWed, 13 Sep 2017 14:09:04 +0000 (UTC)" ], "DomainKey-Signature": "a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id\n\t:list-unsubscribe:list-archive:list-post:list-help:sender:date\n\t:from:to:subject:message-id:mime-version:content-type; q=dns; s=\n\tdefault; b=J5rfE8NG/u2z7tVNpX8uVZ8YC9k2BeIPjRAzDH6wtAD0O4jpwY/0y\n\tc0ZS013aBIkp5PuH5mqC3dXxR2UkQ4pCBTBKLOp6A5J1KFTRlO94pnneC9PBbstJ\n\tqjtTp7RnJ6CJxK1fL5gnpJrUTJ+YvJmvIliFDwhQrU134W2UlXeuYE=", "DKIM-Signature": "v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id\n\t:list-unsubscribe:list-archive:list-post:list-help:sender:date\n\t:from:to:subject:message-id:mime-version:content-type; s=\n\tdefault; bh=3j45ilSs2dE6xP6Ttegu2Ec9E+0=; b=ALrs41Qxnkw0IsWQc4q9\n\tlYefxUQyBgxmjBWl6JFXJB3e8nkTRxeeDWfjDAuusSUxUUke3/cI+N9wI7YjCjoz\n\tnCq9+L3aoJQzKFFtQf3dKy4JkRcPHnyywXgAg3YlkWC3LnaGiy2C8raHR6/XRSAC\n\t2ZM9mJO4z5IfqMoKPO4vnFM=", "Mailing-List": "contact gcc-patches-help@gcc.gnu.org; run by ezmlm", "Precedence": "bulk", "List-Id": "<gcc-patches.gcc.gnu.org>", "List-Unsubscribe": "<mailto:gcc-patches-unsubscribe-incoming=patchwork.ozlabs.org@gcc.gnu.org>", "List-Archive": "<http://gcc.gnu.org/ml/gcc-patches/>", "List-Post": "<mailto:gcc-patches@gcc.gnu.org>", "List-Help": "<mailto:gcc-patches-help@gcc.gnu.org>", "Sender": "gcc-patches-owner@gcc.gnu.org", "X-Virus-Found": "No", "X-Spam-SWARE-Status": "No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0,\n\tGIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RP_MATCHES_RCVD,\n\tSPF_HELO_PASS autolearn=ham version=3.3.2 spammy=Duration", "X-Spam-User": "qpsmtpd, 2 recipients", "X-HELO": "mx1.redhat.com", "DMARC-Filter": "OpenDMARC Filter v1.3.2 mx1.redhat.com F0BE3356DA", "Date": "Wed, 13 Sep 2017 15:09:03 +0100", "From": "Jonathan Wakely <jwakely@redhat.com>", "To": "libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org", "Subject": "[PATCH] PR libstdc++/81468 constrain std::chrono::time_point\n\tconstructor", "Message-ID": "<20170913140903.GA8606@redhat.com>", "MIME-Version": "1.0", "Content-Type": "multipart/mixed; boundary=\"a8Wt8u1KmwUX3Y2C\"", "Content-Disposition": "inline", "X-Clacks-Overhead": "GNU Terry Pratchett", "User-Agent": "Mutt/1.8.3 (2017-05-23)" }, "content": "Howard reported this bug, caused by a missing SFINAE constraint on a\nstd::chrono::time_point constructor.\n\nI've also done a bit of simplification using alias templates.\n\n\tPR libstdc++/81468\n\t* include/std/chrono (__enable_if_is_duration)\n\t(__disable_if_is_duration): New alias templates to simplify SFINAE.\n\t(duration_cast, floor, ceil): Use __enable_if_is_duration.\n\t(duration::__is_float, duration::__is_harmonic): New alias templates\n\tto simplify SFINAE.\n\t(duration::duration(const _Rep2&)): Use _Require, __is_float and\n\t__is_harmonic.\n\t(duration::duration(const duration<_Rep2, _Period2>&)): Likewise.\n\t(__common_rep_type): Remove, replace with ...\n\t(__common_rep_t): New alias template.\n\t(operator*, operator/, operator%): Use __common_rep_t and\n\t__disable_if_is_duration.\n\t(time_point::time_point(const time_point<clock, _Dur2>&)): Add missing\n\tconstraint from LWG DR 1177.\n\t* testsuite/20_util/duration/cons/dr1177.cc: New.\n\t* testsuite/20_util/duration/literals/range.cc: Update dg-error line.\n\t* testsuite/20_util/duration/requirements/typedefs_neg1.cc: Likewise.\n\t* testsuite/20_util/duration/requirements/typedefs_neg2.cc: Likewise.\n\t* testsuite/20_util/duration/requirements/typedefs_neg3.cc: Likewise.\n\t* testsuite/20_util/time_point/cons/81468.cc: New.\n\nTested on powerp64le-linux, committed to trunk.\ncommit e06db0fa47676eeb386bfd1a582a005d341fb678\nAuthor: Jonathan Wakely <jwakely@redhat.com>\nDate: Wed Sep 13 13:00:50 2017 +0100\n\n PR libstdc++/81468 constrain std::chrono::time_point constructor\n \n PR libstdc++/81468\n * include/std/chrono (__enable_if_is_duration)\n (__disable_if_is_duration): New alias templates to simplify SFINAE.\n (duration_cast, floor, ceil): Use __enable_if_is_duration.\n (duration::__is_float, duration::__is_harmonic): New alias templates\n to simplify SFINAE.\n (duration::duration(const _Rep2&)): Use _Require, __is_float and\n __is_harmonic.\n (duration::duration(const duration<_Rep2, _Period2>&)): Likewise.\n (__common_rep_type): Remove, replace with ...\n (__common_rep_t): New alias template.\n (operator*, operator/, operator%): Use __common_rep_t and\n __disable_if_is_duration.\n (time_point::time_point(const time_point<clock, _Dur2>&)): Add missing\n constraint from LWG DR 1177.\n * testsuite/20_util/duration/cons/dr1177.cc: New.\n * testsuite/20_util/duration/literals/range.cc: Update dg-error line.\n * testsuite/20_util/duration/requirements/typedefs_neg1.cc: Likewise.\n * testsuite/20_util/duration/requirements/typedefs_neg2.cc: Likewise.\n * testsuite/20_util/duration/requirements/typedefs_neg3.cc: Likewise.\n * testsuite/20_util/time_point/cons/81468.cc: New.", "diff": "diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono\nindex 1bcbf524a7b..fc058fcd8d8 100644\n--- a/libstdc++-v3/include/std/chrono\n+++ b/libstdc++-v3/include/std/chrono\n@@ -179,10 +179,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n : std::true_type\n { };\n \n+ template<typename _Tp>\n+ using __enable_if_is_duration\n+\t= typename enable_if<__is_duration<_Tp>::value, _Tp>::type;\n+\n+ template<typename _Tp>\n+ using __disable_if_is_duration\n+\t= typename enable_if<!__is_duration<_Tp>::value, _Tp>::type;\n+\n /// duration_cast\n template<typename _ToDur, typename _Rep, typename _Period>\n- constexpr typename enable_if<__is_duration<_ToDur>::value,\n-\t\t\t\t _ToDur>::type\n+ constexpr __enable_if_is_duration<_ToDur>\n duration_cast(const duration<_Rep, _Period>& __d)\n {\n \ttypedef typename _ToDur::period\t\t\t\t__to_period;\n@@ -211,7 +218,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n # define __cpp_lib_chrono 201510\n \n template<typename _ToDur, typename _Rep, typename _Period>\n- constexpr enable_if_t<__is_duration<_ToDur>::value, _ToDur>\n+ constexpr __enable_if_is_duration<_ToDur>\n floor(const duration<_Rep, _Period>& __d)\n {\n \tauto __to = chrono::duration_cast<_ToDur>(__d);\n@@ -221,7 +228,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n }\n \n template<typename _ToDur, typename _Rep, typename _Period>\n- constexpr enable_if_t<__is_duration<_ToDur>::value, _ToDur>\n+ constexpr __enable_if_is_duration<_ToDur>\n ceil(const duration<_Rep, _Period>& __d)\n {\n \tauto __to = chrono::duration_cast<_ToDur>(__d);\n@@ -294,6 +301,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n template<typename _Rep, typename _Period>\n struct duration\n {\n+ private:\n+\ttemplate<typename _Rep2>\n+\t using __is_float = treat_as_floating_point<_Rep2>;\n+\n+\t// _Period2 is an exact multiple of _Period\n+\ttemplate<typename _Period2>\n+\t using __is_harmonic\n+\t = __bool_constant<ratio_divide<_Period2, _Period>::den == 1>;\n+\n+ public:\n+\n \ttypedef _Rep\t\t\t\t\t\trep;\n \ttypedef _Period \t\t\t\t\tperiod;\n \n@@ -305,22 +323,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \t// 20.11.5.1 construction / copy / destroy\n \tconstexpr duration() = default;\n \n-\t// NB: Make constexpr implicit. This cannot be explicitly\n-\t// constexpr, as any UDT that is not a literal type with a\n-\t// constexpr copy constructor will be ill-formed.\n \tduration(const duration&) = default;\n \n-\ttemplate<typename _Rep2, typename = typename\n-\t enable_if<is_convertible<_Rep2, rep>::value\n-\t\t\t && (treat_as_floating_point<rep>::value\n-\t\t\t || !treat_as_floating_point<_Rep2>::value)>::type>\n+\ttemplate<typename _Rep2, typename = _Require<\n+\t\t is_convertible<_Rep2, rep>,\n+\t\t __or_<__is_float<rep>, __not_<__is_float<_Rep2>>>>>\n \t constexpr explicit duration(const _Rep2& __rep)\n \t : __r(static_cast<rep>(__rep)) { }\n \n-\ttemplate<typename _Rep2, typename _Period2, typename = typename\n-\t enable_if<treat_as_floating_point<rep>::value\n-\t\t\t || (ratio_divide<_Period2, period>::den == 1\n-\t\t\t && !treat_as_floating_point<_Rep2>::value)>::type>\n+\ttemplate<typename _Rep2, typename _Period2, typename = _Require<\n+\t\t __or_<__is_float<rep>,\n+\t\t __and_<__is_harmonic<_Period2>,\n+\t\t\t __not_<__is_float<_Rep2>>>>>>\n \t constexpr duration(const duration<_Rep2, _Period2>& __d)\n \t : __r(duration_cast<duration>(__d).count()) { }\n \n@@ -455,18 +469,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \treturn __cd(__cd(__lhs).count() - __cd(__rhs).count());\n }\n \n- template<typename _Rep1, typename _Rep2, bool =\n-\t is_convertible<_Rep2,\n-\t\t\t typename common_type<_Rep1, _Rep2>::type>::value>\n- struct __common_rep_type { };\n-\n- template<typename _Rep1, typename _Rep2>\n- struct __common_rep_type<_Rep1, _Rep2, true>\n- { typedef typename common_type<_Rep1, _Rep2>::type type; };\n+ // SFINAE helper to obtain common_type<_Rep1, _Rep2> only if _Rep2\n+ // is implicitly convertible to it.\n+ template<typename _Rep1, typename _Rep2,\n+\t typename _CRep = typename common_type<_Rep1, _Rep2>::type>\n+ using __common_rep_t\n+\t= typename enable_if<is_convertible<_Rep2, _CRep>::value, _CRep>::type;\n \n template<typename _Rep1, typename _Period, typename _Rep2>\n- constexpr\n- duration<typename __common_rep_type<_Rep1, _Rep2>::type, _Period>\n+ constexpr duration<__common_rep_t<_Rep1, _Rep2>, _Period>\n operator*(const duration<_Rep1, _Period>& __d, const _Rep2& __s)\n {\n \ttypedef duration<typename common_type<_Rep1, _Rep2>::type, _Period>\n@@ -475,14 +486,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n }\n \n template<typename _Rep1, typename _Rep2, typename _Period>\n- constexpr\n- duration<typename __common_rep_type<_Rep2, _Rep1>::type, _Period>\n+ constexpr duration<__common_rep_t<_Rep2, _Rep1>, _Period>\n operator*(const _Rep1& __s, const duration<_Rep2, _Period>& __d)\n { return __d * __s; }\n \n template<typename _Rep1, typename _Period, typename _Rep2>\n- constexpr duration<typename __common_rep_type<_Rep1, typename\n-\tenable_if<!__is_duration<_Rep2>::value, _Rep2>::type>::type, _Period>\n+ constexpr\n+ duration<__common_rep_t<_Rep1, __disable_if_is_duration<_Rep2>>, _Period>\n operator/(const duration<_Rep1, _Period>& __d, const _Rep2& __s)\n {\n \ttypedef duration<typename common_type<_Rep1, _Rep2>::type, _Period>\n@@ -504,8 +514,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \n // DR 934.\n template<typename _Rep1, typename _Period, typename _Rep2>\n- constexpr duration<typename __common_rep_type<_Rep1, typename\n-\tenable_if<!__is_duration<_Rep2>::value, _Rep2>::type>::type, _Period>\n+ constexpr\n+ duration<__common_rep_t<_Rep1, __disable_if_is_duration<_Rep2>>, _Period>\n operator%(const duration<_Rep1, _Period>& __d, const _Rep2& __s)\n {\n \ttypedef duration<typename common_type<_Rep1, _Rep2>::type, _Period>\n@@ -614,7 +624,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION\n \t{ }\n \n \t// conversions\n-\ttemplate<typename _Dur2>\n+\ttemplate<typename _Dur2,\n+\t\t typename = _Require<is_convertible<_Dur2, _Dur>>>\n \t constexpr time_point(const time_point<clock, _Dur2>& __t)\n \t : __d(__t.time_since_epoch())\n \t { }\ndiff --git a/libstdc++-v3/testsuite/20_util/duration/cons/dr1177.cc b/libstdc++-v3/testsuite/20_util/duration/cons/dr1177.cc\nnew file mode 100644\nindex 00000000000..28c881ccc79\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/20_util/duration/cons/dr1177.cc\n@@ -0,0 +1,41 @@\n+// Copyright (C) 2017 Free Software Foundation, Inc.\n+//\n+// This file is part of the GNU ISO C++ Library. This library is free\n+// software; you can redistribute it and/or modify it under the\n+// terms of the GNU General Public License as published by the\n+// Free Software Foundation; either version 3, or (at your option)\n+// any later version.\n+\n+// This library is distributed in the hope that it will be useful,\n+// but WITHOUT ANY WARRANTY; without even the implied warranty of\n+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n+// GNU General Public License for more details.\n+\n+// You should have received a copy of the GNU General Public License along\n+// with this library; see the file COPYING3. If not see\n+// <http://www.gnu.org/licenses/>.\n+\n+// { dg-do compile { target c++11 } }\n+\n+#include <chrono>\n+#include <type_traits>\n+\n+using namespace std;\n+using namespace std::chrono;\n+\n+// DR 1177\n+static_assert(is_constructible<duration<float>, duration<double>>{},\n+ \"can convert duration with one floating point rep to another\");\n+static_assert(is_constructible<duration<float>, duration<int>>{},\n+ \"can convert duration with integral rep to one with floating point rep\");\n+static_assert(!is_constructible<duration<int>, duration<float>>{},\n+ \"cannot convert duration with floating point rep to one with integral rep\");\n+static_assert(is_constructible<duration<int>, duration<long>>{},\n+ \"can convert duration with one integral rep to another\");\n+\n+static_assert(!is_constructible<duration<int>, duration<int, ratio<2,3>>>{},\n+ \"cannot convert duration to one with different period\");\n+static_assert(is_constructible<duration<float>, duration<int, ratio<2,3>>>{},\n+ \"unless it has a floating-point representation\");\n+static_assert(is_constructible<duration<float>, duration<int, ratio<1,3>>>{},\n+ \"or a period that is an integral multiple of the original\");\ndiff --git a/libstdc++-v3/testsuite/20_util/duration/literals/range.cc b/libstdc++-v3/testsuite/20_util/duration/literals/range.cc\nindex b5105dff38b..36e71eea72b 100644\n--- a/libstdc++-v3/testsuite/20_util/duration/literals/range.cc\n+++ b/libstdc++-v3/testsuite/20_util/duration/literals/range.cc\n@@ -26,6 +26,6 @@ test01()\n \n // std::numeric_limits<int64_t>::max() == 9223372036854775807;\n auto h = 9223372036854775808h;\n- // { dg-error \"cannot be represented\" \"\" { target *-*-* } 880 }\n+ // { dg-error \"cannot be represented\" \"\" { target *-*-* } 891 }\n }\n // { dg-prune-output \"in constexpr expansion\" } // needed for -O0\ndiff --git a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg1.cc b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg1.cc\nindex 17f74187098..d57f6dedd66 100644\n--- a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg1.cc\n+++ b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg1.cc\n@@ -30,4 +30,4 @@ void test01()\n test_type d; // { dg-error \"required from here\" }\n }\n \n-// { dg-error \"rep cannot be a duration\" \"\" { target *-*-* } 300 }\n+// { dg-error \"rep cannot be a duration\" \"\" { target *-*-* } 318 }\ndiff --git a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg2.cc b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg2.cc\nindex 282a9dbdc85..39283b2cb74 100644\n--- a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg2.cc\n+++ b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg2.cc\n@@ -31,5 +31,5 @@ void test01()\n test_type d;\t\t\t// { dg-error \"required from here\" }\n }\n \n-// { dg-error \"must be a specialization of ratio\" \"\" { target *-*-* } 301 }\n+// { dg-error \"must be a specialization of ratio\" \"\" { target *-*-* } 319 }\n // { dg-prune-output \"not a member\" }\ndiff --git a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg3.cc b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg3.cc\nindex c57f9d947a5..9beaa83fbfa 100644\n--- a/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg3.cc\n+++ b/libstdc++-v3/testsuite/20_util/duration/requirements/typedefs_neg3.cc\n@@ -32,4 +32,4 @@ void test01()\n test_type d; // { dg-error \"required from here\" }\n }\n \n-// { dg-error \"period must be positive\" \"\" { target *-*-* } 303 }\n+// { dg-error \"period must be positive\" \"\" { target *-*-* } 321 }\ndiff --git a/libstdc++-v3/testsuite/20_util/time_point/cons/81468.cc b/libstdc++-v3/testsuite/20_util/time_point/cons/81468.cc\nnew file mode 100644\nindex 00000000000..30d1c4a5ac7\n--- /dev/null\n+++ b/libstdc++-v3/testsuite/20_util/time_point/cons/81468.cc\n@@ -0,0 +1,34 @@\n+// Copyright (C) 2017 Free Software Foundation, Inc.\n+//\n+// This file is part of the GNU ISO C++ Library. This library is free\n+// software; you can redistribute it and/or modify it under the\n+// terms of the GNU General Public License as published by the\n+// Free Software Foundation; either version 3, or (at your option)\n+// any later version.\n+\n+// This library is distributed in the hope that it will be useful,\n+// but WITHOUT ANY WARRANTY; without even the implied warranty of\n+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n+// GNU General Public License for more details.\n+\n+// You should have received a copy of the GNU General Public License along\n+// with this library; see the file COPYING3. If not see\n+// <http://www.gnu.org/licenses/>.\n+\n+// { dg-do compile { target c++11 } }\n+\n+#include <chrono>\n+#include <type_traits>\n+\n+using namespace std;\n+using namespace std::chrono;\n+\n+template <class Duration>\n+ using sys_time = time_point<system_clock, Duration>;\n+\n+static_assert(is_constructible<sys_time<milliseconds>, sys_time<seconds>>{},\n+ \"Can construct time_point from one with lower precision duration\");\n+\n+// PR libstdc++/81468 - DR 1177\n+static_assert(!is_constructible<sys_time<seconds>, sys_time<milliseconds>>{},\n+ \"Cannot construct time_point from one with higher precision duration\");\n", "prefixes": [] }