* [PATCH] libstdc++: Add compile-time checks to__glibcxx_assert [PR 71960]
@ 2020-08-26 16:48 Jonathan Wakely
2020-09-01 19:55 ` Jonathan Wakely
0 siblings, 1 reply; 2+ messages in thread
From: Jonathan Wakely @ 2020-08-26 16:48 UTC (permalink / raw)
To: libstdc++, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1666 bytes --]
This change evaluates __glibcxx_assert checks unconditionally when a
function is being constant evaluated (when std::is_constant_evaluated()
is true). If the check fails, compilation will fail with an error.
If the function isn't being constant evaluated, the normal runtime check
will be done if enabled by _GLIBCXX_ASSERTIONS or _GLIBCXX_DEBUG, the
same as before.
Tangentially, the __glibcxx_assert and _GLIBCXX_PARALLEL_ASSERT macros
are changed to expand to 'do { } while (false)' when assertions are
disabled, instead of expanding to nothing. This avoids -Wempty-body
warnings when a disabled assertion is used in an 'if' or 'else'
statement e.g.
if constexpr (/* precondition is testable */)
__glibcxx_assert(precondition);
a.C:9:27: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
9 | __glibcxx_assert(precondition);
| ^
libstdc++-v3/ChangeLog:
PR libstdc++/71960
* include/bits/c++config (__glibcxx_assert_impl): Remove
do-while so that uses of the macro need to add it.
(__glibcxx_assert): Rename macro for runtime assertions
to __glibcxx_assert_2.
(__glibcxx_assert_1): Define macro for constexpr assertions.
(__glibcxx_assert): Define macro for constexpr and runtime
assertions.
* include/bits/range_access.h (ranges::advance): Remove
redundant precondition checks during constant evaluation.
* include/parallel/base.h (_GLIBCXX_PARALLEL_ASSERT): Always
use do-while in macro expansion.
* include/std/ranges (iota_view::iota_view(W, B)): Remove
redundant braces.
Not yet committed.
Tested powerpc64le-linux, normal and debug modes.
Thoughts?
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 5791 bytes --]
commit 4e71993e73cabcba16d23f43c0d000778e812884
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Wed Aug 26 17:45:36 2020
libstdc++: Add compile-time checks to__glibcxx_assert [PR 71960]
This change evaluates __glibcxx_assert checks unconditionally when a
function is being constant evaluated (when std::is_constant_evaluated()
is true). If the check fails, compilation will fail with an error.
If the function isn't being constant evaluated, the normal runtime check
will be done if enabled by _GLIBCXX_ASSERTIONS or _GLIBCXX_DEBUG, the
same as before.
Tangentially, the __glibcxx_assert and _GLIBCXX_PARALLEL_ASSERT macros
are changed to expand to 'do { } while (false)' when assertions are
disabled, instead of expanding to nothing. This avoids -Wempty-body
warnings when a disabled assertion is used in an 'if' or 'else'
statement e.g.
if constexpr (/* precondition is testable */)
__glibcxx_assert(precondition);
a.C:9:27: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
9 | __glibcxx_assert(precondition);
| ^
libstdc++-v3/ChangeLog:
PR libstdc++/71960
* include/bits/c++config (__glibcxx_assert_impl): Remove
do-while so that uses of the macro need to add it.
(__glibcxx_assert): Rename macro for runtime assertions
to __glibcxx_assert_2.
(__glibcxx_assert_1): Define macro for constexpr assertions.
(__glibcxx_assert): Define macro for constexpr and runtime
assertions.
* include/bits/range_access.h (ranges::advance): Remove
redundant precondition checks during constant evaluation.
* include/parallel/base.h (_GLIBCXX_PARALLEL_ASSERT): Always
use do-while in macro expansion.
* include/std/ranges (iota_view::iota_view(W, B)): Remove
redundant braces.
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index de28acea6b7..badf9d01a04 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -477,19 +477,16 @@ namespace std
__builtin_abort();
}
}
-#define __glibcxx_assert_impl(_Condition) \
- do \
- { \
- if (! (_Condition)) \
- std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
- #_Condition); \
- } while (false)
+#define __glibcxx_assert_impl(_Condition) \
+ if (!bool(_Condition)) \
+ std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \
+ #_Condition)
#endif
#if defined(_GLIBCXX_ASSERTIONS)
-# define __glibcxx_assert(_Condition) __glibcxx_assert_impl(_Condition)
+# define __glibcxx_assert_2(_Condition) __glibcxx_assert_impl(_Condition)
#else
-# define __glibcxx_assert(_Condition)
+# define __glibcxx_assert_2(_Condition)
#endif
// Macros for race detectors.
@@ -683,6 +680,26 @@ namespace std
# endif
#endif // GCC
+#if _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
+# 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
#if __cplusplus >= 201703L
diff --git a/libstdc++-v3/include/bits/range_access.h b/libstdc++-v3/include/bits/range_access.h
index bafced31ea8..5c5b2fe0c6c 100644
--- a/libstdc++-v3/include/bits/range_access.h
+++ b/libstdc++-v3/include/bits/range_access.h
@@ -987,10 +987,7 @@ namespace ranges
}
else
{
-#ifdef __cpp_lib_is_constant_evaluated
- if (std::is_constant_evaluated() && __n < 0)
- throw "attempt to decrement a non-bidirectional iterator";
-#endif
+ // cannot decrement a non-bidirectional iterator
__glibcxx_assert(__n >= 0);
while (__n-- > 0)
++__it;
@@ -1065,10 +1062,7 @@ namespace ranges
}
else
{
-#ifdef __cpp_lib_is_constant_evaluated
- if (std::is_constant_evaluated() && __n < 0)
- throw "attempt to decrement a non-bidirectional iterator";
-#endif
+ // cannot decrement a non-bidirectional iterator
__glibcxx_assert(__n >= 0);
return __n;
}
diff --git a/libstdc++-v3/include/parallel/base.h b/libstdc++-v3/include/parallel/base.h
index 0d1c2644e8f..973a2dcd514 100644
--- a/libstdc++-v3/include/parallel/base.h
+++ b/libstdc++-v3/include/parallel/base.h
@@ -420,9 +420,10 @@ namespace __gnu_parallel
}
#if _GLIBCXX_PARALLEL_ASSERTIONS && defined(__glibcxx_assert_impl)
-#define _GLIBCXX_PARALLEL_ASSERT(_Condition) __glibcxx_assert_impl(_Condition)
+# define _GLIBCXX_PARALLEL_ASSERT(_Condition) \
+ do { __glibcxx_assert_impl(_Condition); } while (false)
#else
-#define _GLIBCXX_PARALLEL_ASSERT(_Condition)
+# define _GLIBCXX_PARALLEL_ASSERT(_Condition) do { } while (false)
#endif
} //namespace __gnu_parallel
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 9d22b138082..7d135536b0c 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -860,9 +860,7 @@ namespace ranges
: _M_value(__value), _M_bound(__bound)
{
if constexpr (totally_ordered_with<_Winc, _Bound>)
- {
- __glibcxx_assert( bool(__value <= __bound) );
- }
+ __glibcxx_assert( bool(__value <= __bound) );
}
constexpr _Iterator
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] libstdc++: Add compile-time checks to__glibcxx_assert [PR 71960]
2020-08-26 16:48 [PATCH] libstdc++: Add compile-time checks to__glibcxx_assert [PR 71960] Jonathan Wakely
@ 2020-09-01 19:55 ` Jonathan Wakely
0 siblings, 0 replies; 2+ messages in thread
From: Jonathan Wakely @ 2020-09-01 19:55 UTC (permalink / raw)
To: libstdc++, gcc-patches
On 26/08/20 17:48 +0100, Jonathan Wakely wrote:
>This change evaluates __glibcxx_assert checks unconditionally when a
>function is being constant evaluated (when std::is_constant_evaluated()
>is true). If the check fails, compilation will fail with an error.
>
>If the function isn't being constant evaluated, the normal runtime check
>will be done if enabled by _GLIBCXX_ASSERTIONS or _GLIBCXX_DEBUG, the
>same as before.
>
>Tangentially, the __glibcxx_assert and _GLIBCXX_PARALLEL_ASSERT macros
>are changed to expand to 'do { } while (false)' when assertions are
>disabled, instead of expanding to nothing. This avoids -Wempty-body
>warnings when a disabled assertion is used in an 'if' or 'else'
>statement e.g.
>
> if constexpr (/* precondition is testable */)
> __glibcxx_assert(precondition);
>
>a.C:9:27: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
> 9 | __glibcxx_assert(precondition);
> | ^
>
>libstdc++-v3/ChangeLog:
>
> PR libstdc++/71960
> * include/bits/c++config (__glibcxx_assert_impl): Remove
> do-while so that uses of the macro need to add it.
> (__glibcxx_assert): Rename macro for runtime assertions
> to __glibcxx_assert_2.
> (__glibcxx_assert_1): Define macro for constexpr assertions.
> (__glibcxx_assert): Define macro for constexpr and runtime
> assertions.
> * include/bits/range_access.h (ranges::advance): Remove
> redundant precondition checks during constant evaluation.
> * include/parallel/base.h (_GLIBCXX_PARALLEL_ASSERT): Always
> use do-while in macro expansion.
> * include/std/ranges (iota_view::iota_view(W, B)): Remove
> redundant braces.
>
>Not yet committed.
>
>Tested powerpc64le-linux, normal and debug modes.
>
>Thoughts?
Pushed to master now. Let's see if it breaks anything!
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2020-09-01 19:55 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-26 16:48 [PATCH] libstdc++: Add compile-time checks to__glibcxx_assert [PR 71960] Jonathan Wakely
2020-09-01 19:55 ` Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).