public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/meissner/heads/work013-orig)] libstdc++: Add compile-time checks to__glibcxx_assert [PR 71960]
@ 2020-09-01 20:33 Michael Meissner
  0 siblings, 0 replies; only message in thread
From: Michael Meissner @ 2020-09-01 20:33 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="us-ascii", Size: 6166 bytes --]

https://gcc.gnu.org/g:10f51543bb81cc953792270b40a9c812049e8b4c

commit 10f51543bb81cc953792270b40a9c812049e8b4c
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Sep 1 20:52:26 2020 +0100

    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:
---
 libstdc++-v3/include/bits/c++config      | 35 ++++++++++++++++++++++++--------
 libstdc++-v3/include/bits/range_access.h | 10 ++-------
 libstdc++-v3/include/parallel/base.h     |  5 +++--
 libstdc++-v3/include/std/ranges          |  4 +---
 4 files changed, 32 insertions(+), 22 deletions(-)

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 2d0017f1750..054ffe85d0f 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] only message in thread

only message in thread, other threads:[~2020-09-01 20:33 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-01 20:33 [gcc(refs/users/meissner/heads/work013-orig)] libstdc++: Add compile-time checks to__glibcxx_assert [PR 71960] Michael Meissner

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).