From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id ABD04398043F for ; Thu, 20 May 2021 20:49:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org ABD04398043F Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-530-RVYOCCoQOqiNZkxZhb5Emw-1; Thu, 20 May 2021 16:49:23 -0400 X-MC-Unique: RVYOCCoQOqiNZkxZhb5Emw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 52CC2801106; Thu, 20 May 2021 20:49:22 +0000 (UTC) Received: from localhost (unknown [10.33.36.7]) by smtp.corp.redhat.com (Postfix) with ESMTP id B97DD5C233; Thu, 20 May 2021 20:49:21 +0000 (UTC) Date: Thu, 20 May 2021 21:49:20 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [committed] libstdc++: Use __builtin_unreachable for constexpr assertions [PR 100676] Message-ID: MIME-Version: 1.0 X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/mixed; boundary="ObjeNRXA1F54Ynxp" Content-Disposition: inline X-Spam-Status: No, score=-14.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=unavailable autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libstdc++@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++ mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 May 2021 20:49:27 -0000 --ObjeNRXA1F54Ynxp Content-Type: text/plain; charset=us-ascii Content-Disposition: inline The current implementation of compile-time precondition checks causes compilation to fail by calling a non-constexpr function declared at block scope. This breaks the CUDA compiler, which wraps some libstdc++ headers in a pragma that declares everything as a __host__ __device__ function, but others are not wrapped and so everything is a __host__ function. The local declaration thus gets redeclared as two different types of function, which doesn't work. Just use __builtin_unreachable to make constant evaluation fail, instead of the local function declaration. Also simplify the assertion macros, which has the side effect of giving simpler compilation errors when using Clang. libstdc++-v3/ChangeLog: PR libstdc++/100676 * include/bits/c++config (__glibcxx_assert_1): Rename to ... (__glibcxx_constexpr_assert): ... this. (__glibcxx_assert_impl): Use __glibcxx_constexpr_assert. (__glibcxx_assert): Define as either __glibcxx_constexpr_assert or __glibcxx_assert_impl. (__glibcxx_assert_2): Remove * include/debug/macros.h (_GLIBCXX_DEBUG_VERIFY_AT_F): Use __glibcxx_constexpr_assert instead of __glibcxx_assert_1. * testsuite/21_strings/basic_string_view/element_access/char/back_constexpr_neg.cc: Adjust expected error. * testsuite/21_strings/basic_string_view/element_access/char/constexpr_neg.cc: Likewise. * testsuite/21_strings/basic_string_view/element_access/char/front_constexpr_neg.cc: Likewise. Likewise. * testsuite/21_strings/basic_string_view/element_access/wchar_t/back_constexpr_neg.cc: Likewise. * testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc: Likewise. * testsuite/21_strings/basic_string_view/element_access/wchar_t/front_constexpr_neg.cc: Likewise. * testsuite/23_containers/span/back_neg.cc: Likewise. * testsuite/23_containers/span/front_neg.cc: Likewise. * testsuite/23_containers/span/index_op_neg.cc: Likewise. Tested powerpc64le-linux. Committed to trunk. --ObjeNRXA1F54Ynxp Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="patch.txt" commit 6b42b5a8a207de5e021a2916281f46bcd60b20d2 Author: Jonathan Wakely Date: Thu May 20 16:39:06 2021 libstdc++: Use __builtin_unreachable for constexpr assertions [PR 100676] The current implementation of compile-time precondition checks causes compilation to fail by calling a non-constexpr function declared at block scope. This breaks the CUDA compiler, which wraps some libstdc++ headers in a pragma that declares everything as a __host__ __device__ function, but others are not wrapped and so everything is a __host__ function. The local declaration thus gets redeclared as two different types of function, which doesn't work. Just use __builtin_unreachable to make constant evaluation fail, instead of the local function declaration. Also simplify the assertion macros, which has the side effect of giving simpler compilation errors when using Clang. libstdc++-v3/ChangeLog: PR libstdc++/100676 * include/bits/c++config (__glibcxx_assert_1): Rename to ... (__glibcxx_constexpr_assert): ... this. (__glibcxx_assert_impl): Use __glibcxx_constexpr_assert. (__glibcxx_assert): Define as either __glibcxx_constexpr_assert or __glibcxx_assert_impl. (__glibcxx_assert_2): Remove * include/debug/macros.h (_GLIBCXX_DEBUG_VERIFY_AT_F): Use __glibcxx_constexpr_assert instead of __glibcxx_assert_1. * testsuite/21_strings/basic_string_view/element_access/char/back_constexpr_neg.cc: Adjust expected error. * testsuite/21_strings/basic_string_view/element_access/char/constexpr_neg.cc: Likewise. * testsuite/21_strings/basic_string_view/element_access/char/front_constexpr_neg.cc: Likewise. Likewise. * testsuite/21_strings/basic_string_view/element_access/wchar_t/back_constexpr_neg.cc: Likewise. * testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc: Likewise. * testsuite/21_strings/basic_string_view/element_access/wchar_t/front_constexpr_neg.cc: Likewise. * testsuite/23_containers/span/back_neg.cc: Likewise. * testsuite/23_containers/span/front_neg.cc: Likewise. * testsuite/23_containers/span/index_op_neg.cc: Likewise. diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index 72ec91949de..9314117aed8 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -487,6 +487,16 @@ namespace std # define _GLIBCXX_EXTERN_TEMPLATE -1 #endif + +#if __has_builtin(__builtin_is_constant_evaluated) +# define __glibcxx_constexpr_assert(cond) \ + if (__builtin_is_constant_evaluated() && !bool(cond)) \ + __builtin_unreachable() /* precondition violation detected! */ +#else +# define __glibcxx_constexpr_assert(unevaluated) +#endif + + // Assert. #if defined(_GLIBCXX_ASSERTIONS) \ || defined(_GLIBCXX_PARALLEL) || defined(_GLIBCXX_PARALLEL_ASSERTIONS) @@ -506,14 +516,19 @@ namespace std } #define __glibcxx_assert_impl(_Condition) \ if (__builtin_expect(!bool(_Condition), false)) \ + { \ + __glibcxx_constexpr_assert(_Condition); \ std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ - #_Condition) + #_Condition); \ + } #endif #if defined(_GLIBCXX_ASSERTIONS) -# define __glibcxx_assert_2(_Condition) __glibcxx_assert_impl(_Condition) +# define __glibcxx_assert(cond) \ + do { __glibcxx_assert_impl(cond); } while (false) #else -# define __glibcxx_assert_2(_Condition) +# define __glibcxx_assert(cond) \ + do { __glibcxx_constexpr_assert(cond); } while (false) #endif // Macros for race detectors. @@ -736,25 +751,6 @@ namespace std #undef _GLIBCXX_HAS_BUILTIN -#if _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED && __cplusplus >= 201402L -# define __glibcxx_assert_1(_Condition) \ - if (__builtin_is_constant_evaluated()) \ - { \ - void __failed_assertion(); \ - if (!bool(_Condition)) \ - __failed_assertion(); \ - } \ - else -#else -# define __glibcxx_assert_1(_Condition) -#endif - -# define __glibcxx_assert(_Condition) \ - do { \ - __glibcxx_assert_1(_Condition) \ - { __glibcxx_assert_2(_Condition); } \ - } while (false) - // PSTL configuration diff --git a/libstdc++-v3/include/debug/macros.h b/libstdc++-v3/include/debug/macros.h index 9ac52ebd09d..9e1288cf4d9 100644 --- a/libstdc++-v3/include/debug/macros.h +++ b/libstdc++-v3/include/debug/macros.h @@ -45,8 +45,8 @@ #define _GLIBCXX_DEBUG_VERIFY_AT_F(_Cond,_ErrMsg,_File,_Line,_Func) \ do { \ - __glibcxx_assert_1(_Cond) \ - { _GLIBCXX_DEBUG_VERIFY_COND_AT(_Cond,_ErrMsg,_File,_Line,_Func); } \ + __glibcxx_constexpr_assert(_Cond); \ + _GLIBCXX_DEBUG_VERIFY_COND_AT(_Cond,_ErrMsg,_File,_Line,_Func); \ } while (false) #define _GLIBCXX_DEBUG_VERIFY_AT(_Cond,_ErrMsg,_File,_Line) \ 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 index 0f731c9a485..2da90bd954e 100644 --- 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 @@ -32,4 +32,4 @@ back() static_assert(back() != 'a'); // { dg-error "non-constant condition" } // { dg-prune-output "in 'constexpr' expansion" } -// { dg-prune-output "failed_assertion" } +// { dg-prune-output "unreachable" } 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 index 5dd206f1a29..844b62277c5 100644 --- 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 @@ -31,4 +31,4 @@ test() static_assert(test() == 0); // { dg-error "non-constant condition" } // { dg-prune-output "in 'constexpr' expansion" } -// { dg-prune-output "failed_assertion" } +// { dg-prune-output "unreachable" } 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 index 9c846116bb9..d6dceb61a34 100644 --- 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 @@ -32,4 +32,4 @@ front() static_assert(front() != 'a'); // { dg-error "non-constant condition" } // { dg-prune-output "in 'constexpr' expansion" } -// { dg-prune-output "failed_assertion" } +// { dg-prune-output "unreachable" } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/back_constexpr_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/back_constexpr_neg.cc index 26d2d4da54b..798e1a4074d 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/back_constexpr_neg.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/back_constexpr_neg.cc @@ -32,4 +32,4 @@ back() static_assert(back() != L'a'); // { dg-error "non-constant condition" } // { dg-prune-output "in 'constexpr' expansion" } -// { dg-prune-output "failed_assertion" } +// { dg-prune-output "unreachable" } 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 index c853dada7dc..0e22b766b3d 100644 --- 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 @@ -31,4 +31,4 @@ test() static_assert(test() == 0); // { dg-error "non-constant condition" } // { dg-prune-output "in 'constexpr' expansion" } -// { dg-prune-output "failed_assertion" } +// { dg-prune-output "unreachable" } diff --git a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/front_constexpr_neg.cc b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/front_constexpr_neg.cc index fdcabd7363d..f49774a0bdd 100644 --- a/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/front_constexpr_neg.cc +++ b/libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/front_constexpr_neg.cc @@ -32,4 +32,4 @@ front() static_assert(front() != L'a'); // { dg-error "non-constant condition" } // { dg-prune-output "in 'constexpr' expansion" } -// { dg-prune-output "failed_assertion" } +// { dg-prune-output "unreachable" } diff --git a/libstdc++-v3/testsuite/23_containers/span/back_neg.cc b/libstdc++-v3/testsuite/23_containers/span/back_neg.cc index 0289ece7a50..ce00aa8868f 100644 --- a/libstdc++-v3/testsuite/23_containers/span/back_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/back_neg.cc @@ -31,5 +31,5 @@ test01(bool b) static_assert(test01(false)); static_assert(test01(true)); // { dg-error "non-constant" } -// { dg-error "assert" "" { target *-*-* } 0 } +// { dg-error "unreachable" "" { target *-*-* } 0 } // { dg-prune-output "in 'constexpr' expansion" } diff --git a/libstdc++-v3/testsuite/23_containers/span/front_neg.cc b/libstdc++-v3/testsuite/23_containers/span/front_neg.cc index dfad9f8a542..a6efc7dd836 100644 --- a/libstdc++-v3/testsuite/23_containers/span/front_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/front_neg.cc @@ -31,5 +31,5 @@ test01(bool b) static_assert(test01(false)); static_assert(test01(true)); // { dg-error "non-constant" } -// { dg-error "assert" "" { target *-*-* } 0 } +// { dg-error "unreachable" "" { target *-*-* } 0 } // { dg-prune-output "in 'constexpr' expansion" } diff --git a/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc b/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc index 378ae05e0ea..2dce639819c 100644 --- a/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc @@ -31,5 +31,5 @@ test01(bool b) static_assert(test01(false)); static_assert(test01(true)); // { dg-error "non-constant" } -// { dg-error "assert" "" { target *-*-* } 0 } +// { dg-error "unreachable" "" { target *-*-* } 0 } // { dg-prune-output "in 'constexpr' expansion" } --ObjeNRXA1F54Ynxp--