aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2021-05-20 16:39:06 +0100
committerJonathan Wakely <jwakely@redhat.com>2021-05-20 20:49:57 +0100
commit6b42b5a8a207de5e021a2916281f46bcd60b20d2 (patch)
tree4cfd4f43c10fdaf4acac32b280c4e625f74117c6
parentee336ecb2a7161bc28f6c5343d97870a8d15e177 (diff)
downloadgcc-6b42b5a8a207de5e021a2916281f46bcd60b20d2.zip
gcc-6b42b5a8a207de5e021a2916281f46bcd60b20d2.tar.gz
gcc-6b42b5a8a207de5e021a2916281f46bcd60b20d2.tar.bz2
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.
-rw-r--r--libstdc++-v3/include/bits/c++config40
-rw-r--r--libstdc++-v3/include/debug/macros.h4
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/back_constexpr_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/constexpr_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/char/front_constexpr_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/back_constexpr_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/constexpr_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string_view/element_access/wchar_t/front_constexpr_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/span/back_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/span/front_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc2
11 files changed, 29 insertions, 33 deletions
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 72ec919..9314117 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 9ac52eb..9e1288c 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 0f731c9..2da90bd 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 5dd206f..844b622 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 9c84611..d6dceb6 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 26d2d4d..798e1a4 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 c853dad..0e22b76 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 fdcabd7..f49774a 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 0289ece..ce00aa8 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 dfad9f8..a6efc7d 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 378ae05..2dce639 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" }