From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 51663 invoked by alias); 11 Feb 2020 06:35:32 -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 51643 invoked by uid 89); 11 Feb 2020 06:35:32 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.1 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT,RCVD_IN_DNSWL_NONE,RCVD_IN_SBL_CSS,SPF_PASS autolearn=ham version=3.3.1 spammy=Dans, 22014, erreur, Assertion X-HELO: mail-wr1-f66.google.com Received: from mail-wr1-f66.google.com (HELO mail-wr1-f66.google.com) (209.85.221.66) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 11 Feb 2020 06:35:29 +0000 Received: by mail-wr1-f66.google.com with SMTP id u6so10796319wrt.0; Mon, 10 Feb 2020 22:35:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:subject:to:message-id:date:user-agent:mime-version :content-language; bh=g44gGznBPNi/y9G1NF49TkWEETcW72rG8O1Htl3J3DM=; b=VF0V+rWlS3I/U75HUtoNmy0ILEhFX7iiRBAPzzB3AC5Y3/T/YBkvKggFn+673GnEp0 sSd2SpIBz0OWxxbJFCr+FhO/3DsUpNdOK872UaZJ5SDs3ETue+C0qMSkyFY4q8pF6MFV tlnONxUdai0s4VueiY2k4jmXRTzgpUdPoHsxnOswkwoGp69vzKfmQn/b1XuonVGmAJ5u vAROc2bs+yI48Dg+gm+Z5HP7NzjmiQEm2lgL/DpDPBoY6mLg9tWaRYhDvbDma/MvJYJB cslgWhY3MegYUrtuqnMlobUEZCFmsumRxv8LkHOXEEdOJTlq2WWsocF2B2CVrINk+e94 m5gQ== Return-Path: Received: from [10.34.7.159] ([109.190.253.11]) by smtp.googlemail.com with ESMTPSA id i204sm2447642wma.44.2020.02.10.22.35.24 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 10 Feb 2020 22:35:25 -0800 (PST) From: =?UTF-8?Q?Fran=c3=a7ois_Dumont?= Subject: [PATCH] Make __glibcxx_assert constexpr compatible To: "libstdc++@gcc.gnu.org" , gcc-patches Message-ID: <479285f2-79dd-0ecb-7c19-274b5be7d1f9@gmail.com> Date: Tue, 11 Feb 2020 06:35:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.4.1 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------BE38C26DFD3B9387DAC61396" X-SW-Source: 2020-02/txt/msg00620.txt.bz2 This is a multi-part message in MIME format. --------------BE38C26DFD3B9387DAC61396 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-length: 3543 By making __glibcxx_assert constexpr compatible we can get rid of a FIXME in basic_string_view and so fix following XPASS in _GLIBCXX_DEBUG modes. XPASS: 21_strings/basic_string_view/element_access/char/2.cc execution test XPASS: 21_strings/basic_string_view/element_access/wchar_t/2.cc execution test Should I also rename those in 2_neg.cc ? I had to move the assert block in c++config to benefit from _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED definition. The generation of the compilation error is not very nice but it is still better than no error and we can see the assertion: /home/fdt/dev/gcc/git/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc:31:22: erreur: condition non constante pour l'assertion statique    31 | static_assert(test() == 0); // { dg-error "non-constant condition" }       |               ~~~~~~~^~~~ Dans le fichier inclus depuis /home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/limits:42,                  depuis /home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/string_view:40,                  depuis /home/fdt/dev/gcc/git/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc:21: /home/fdt/dev/gcc/git/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc:31:19: dans l'expansion « constexpr » de « test() » /home/fdt/dev/gcc/git/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc:28:13: dans l'expansion « constexpr » de « s.std::basic_string_view::operator[](4) » /home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/string_view:206:2: erreur: inline assembly is not a constant expression   206 |  __glibcxx_assert(__pos < this->_M_len);       |  ^~~~~~~~~~~~~~~~ /home/fdt/dev/gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/string_view:206:2: note: only unevaluated inline assembly is allowed in a « constexpr » function in C++2a             * include/bits/c++config [_GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED](__glibcxx_assert_impl):             New.             * include/std/string_view (basic_string_view<>:operator[](size_type)):             Restore __glibcxx_assert.             (basic_string_view<>::front()): Likewise.             (basic_string_view<>::back()): Likewise.             * testsuite/21_strings/basic_string_view/element_access/char/back_constexpr_neg.cc:             New.             * testsuite/21_strings/basic_string_view/element_access/char/constexpr.cc:             New.             * testsuite/21_strings/basic_string_view/element_access/char/constexpr_neg.cc:             New.             * testsuite/21_strings/basic_string_view/element_access/char/front_back_constexpr.cc:             New.             * testsuite/21_strings/basic_string_view/element_access/char/front_constexpr_neg.cc:             New.             * testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr.cc:             New.             * testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc:             New. Tested under Linux x86_64 normal and debug modes. Ok to commit ? François --------------BE38C26DFD3B9387DAC61396 Content-Type: text/x-patch; charset=UTF-8; name="assert_constexpr.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="assert_constexpr.patch" Content-length: 14887 diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index b1fad59d4b3..4d821627447 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -441,37 +441,6 @@ namespace std # define _GLIBCXX_EXTERN_TEMPLATE -1 #endif -// Assert. -#if defined(_GLIBCXX_ASSERTIONS) \ - || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PARALLEL_ASSERTIONS) -namespace std -{ - // Avoid the use of assert, because we're trying to keep the - // include out of the mix. - extern "C++" inline void - __replacement_assert(const char* __file, int __line, - const char* __function, const char* __condition) - { - __builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line, - __function, __condition); - __builtin_abort(); - } -} -#define __glibcxx_assert_impl(_Condition) \ - do \ - { \ - if (! (_Condition)) \ - std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ - #_Condition); \ - } while (false) -#endif - -#if defined(_GLIBCXX_ASSERTIONS) -# define __glibcxx_assert(_Condition) __glibcxx_assert_impl(_Condition) -#else -# define __glibcxx_assert(_Condition) -#endif - // Macros for race detectors. // _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) and // _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) should be used to explain @@ -663,6 +632,53 @@ namespace std # endif #endif // GCC +// Assert. +#if defined(_GLIBCXX_ASSERTIONS) \ + || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PARALLEL_ASSERTIONS) +namespace std +{ + // Avoid the use of assert, because we're trying to keep the + // include out of the mix. + extern "C++" inline void + __replacement_assert(const char* __file, int __line, + const char* __function, const char* __condition) + { + __builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line, + __function, __condition); + __builtin_abort(); + } +} +# ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED +# define __glibcxx_assert_impl(_Condition) \ + do \ + { \ + if (__builtin_is_constant_evaluated()) \ + { \ + if (!(_Condition)) \ + /* FIXME Generate compilation error here. */ \ + asm("assertion failure"); \ + } \ + else if (! (_Condition)) \ + std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ + #_Condition); \ + } while (false) +# else +# define __glibcxx_assert_impl(_Condition) \ + do \ + { \ + if (! (_Condition)) \ + std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ + #_Condition); \ + } while (false) +# endif +#endif + +#if defined(_GLIBCXX_ASSERTIONS) +# define __glibcxx_assert(_Condition) __glibcxx_assert_impl(_Condition) +#else +# define __glibcxx_assert(_Condition) +#endif + // PSTL configuration #if __cplusplus >= 201703L diff --git a/libstdc++-v3/include/std/string_view b/libstdc++-v3/include/std/string_view index 798cb89a621..84ecb56b5d2 100644 --- a/libstdc++-v3/include/std/string_view +++ b/libstdc++-v3/include/std/string_view @@ -203,8 +203,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr const_reference operator[](size_type __pos) const noexcept { - // TODO: Assert to restore in a way compatible with the constexpr. - // __glibcxx_assert(__pos < this->_M_len); + __glibcxx_assert(__pos < this->_M_len); return *(this->_M_str + __pos); } @@ -221,16 +220,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr const_reference front() const noexcept { - // TODO: Assert to restore in a way compatible with the constexpr. - // __glibcxx_assert(this->_M_len > 0); + __glibcxx_assert(this->_M_len > 0); return *this->_M_str; } constexpr const_reference back() const noexcept { - // TODO: Assert to restore in a way compatible with the constexpr. - // __glibcxx_assert(this->_M_len > 0); + __glibcxx_assert(this->_M_len > 0); return *(this->_M_str + this->_M_len - 1); } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/back_constexpr_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/back_constexpr_neg.cc new file mode 100644 index 00000000000..1bf7f758c57 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/back_constexpr_neg.cc @@ -0,0 +1,35 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++17 -D_GLIBCXX_ASSERTIONS" } +// { dg-do compile { target c++17 xfail *-*-* } } + +#include + +typedef std::string_view string_view_type; + +constexpr char +back() +{ + string_view_type s(""); + return s.back(); +} + +static_assert(back() != 'a'); // { dg-error "non-constant condition" } + +// { dg-prune-output "in 'constexpr' expansion" } +// { dg-prune-output "not a constant expression" } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/constexpr.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/constexpr.cc new file mode 100644 index 00000000000..aa2a08ebe83 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/constexpr.cc @@ -0,0 +1,31 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++17" } +// { dg-do compile { target c++17 } } + +#include + +constexpr char +test() +{ + typedef std::string_view string_view_type; + string_view_type s("abcd"); + return s[0]; +} + +static_assert(test() == 'a'); diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/constexpr_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/constexpr_neg.cc new file mode 100644 index 00000000000..77ad7ba0aeb --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/constexpr_neg.cc @@ -0,0 +1,34 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++17 -D_GLIBCXX_ASSERTIONS" } +// { dg-do compile { target c++17 xfail *-*-* } } + +#include + +constexpr char +test() +{ + typedef std::string_view string_view_type; + string_view_type s("abcd"); + return s[s.length()]; +} + +static_assert(test() == 0); // { dg-error "non-constant condition" } + +// { dg-prune-output "in 'constexpr' expansion" } +// { dg-prune-output "not a constant expression" } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/front_back_constexpr.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/front_back_constexpr.cc new file mode 100644 index 00000000000..7ead45ddcf6 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/front_back_constexpr.cc @@ -0,0 +1,41 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++17" } +// { dg-do compile { target c++17 } } + +#include + +typedef std::string_view string_view_type; + +constexpr char +front() +{ + string_view_type s("abcd"); + return s.front(); +} + +static_assert(front() == 'a'); + +constexpr char +back() +{ + string_view_type s("abcd"); + return s.back(); +} + +static_assert(back() == 'd'); diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/front_constexpr_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/front_constexpr_neg.cc new file mode 100644 index 00000000000..19800739814 --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/front_constexpr_neg.cc @@ -0,0 +1,35 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++17 -D_GLIBCXX_ASSERTIONS" } +// { dg-do compile { target c++17 xfail *-*-* } } + +#include + +typedef std::string_view string_view_type; + +constexpr char +front() +{ + string_view_type s(""); + return s.front(); +} + +static_assert(front() != 'a'); // { dg-error "non-constant condition" } + +// { dg-prune-output "in 'constexpr' expansion" } +// { dg-prune-output "not a constant expression" } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr.cc new file mode 100644 index 00000000000..f4171628e9f --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr.cc @@ -0,0 +1,31 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++17" } +// { dg-do compile { target c++17 } } + +#include + +constexpr wchar_t +test() +{ + typedef std::wstring_view string_view_type; + string_view_type s(L"abcd"); + return s[0]; +} + +static_assert(test() == L'a'); diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc new file mode 100644 index 00000000000..2b1bc68d11c --- /dev/null +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc @@ -0,0 +1,34 @@ +// Copyright (C) 2020 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 +// . + +// { dg-options "-std=gnu++17 -D_GLIBCXX_ASSERTIONS" } +// { dg-do compile { target c++17 xfail *-*-* } } + +#include + +constexpr wchar_t +test() +{ + typedef std::wstring_view string_view_type; + string_view_type s(L"abcd"); + return s[4]; +} + +static_assert(test() == 0); // { dg-error "non-constant condition" } + +// { dg-prune-output "in 'constexpr' expansion" } +// { dg-prune-output "not a constant expression" } --------------BE38C26DFD3B9387DAC61396--