public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
From: "François Dumont" <frs.dumont@gmail.com>
To: Jonathan Wakely <jwakely@redhat.com>
Cc: "libstdc++@gcc.gnu.org" <libstdc++@gcc.gnu.org>,
	gcc-patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH] Help compiler detect invalid code
Date: Fri, 27 Sep 2019 16:24:00 -0000	[thread overview]
Message-ID: <e04cfab3-f80f-f401-b5ec-448f97c69078@gmail.com> (raw)
In-Reply-To: <20190927121109.GY9487@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 1047 bytes --]

On 9/27/19 2:11 PM, Jonathan Wakely wrote:
> On 19/09/19 22:27 +0200, François Dumont wrote:
>> Hi
>>
>>     I start working on making recently added constexpr tests to work 
>> in Debug mode.
>
> The attached patch seems to be necessary for that, right?
>
>
On my side I had done this, almost the same.

For the moment there is a FIXME in macros.h to find out how to generate 
a nice compilation error when the condition is not meant.

static_assert can't be called in this context, too bad.

I also try to define a function with a 
__attribute__((__error__("because"))) attribute. But when I make it 
constexpr gcc complains about missing definition. When I provide a 
definition gcc complains that this attribute must be on a declaration. 
And when I split declaration and definition gcc does not produce the 
expected compilation error.

Unless you have the solution I consider that we need help from the 
front-end.

For the moment if Debug mode finds a problem it will be reported as 
_M_error function not being constexpr !

François


[-- Attachment #2: debug_constexpr.patch --]
[-- Type: text/x-patch, Size: 19688 bytes --]

diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index a672f8b2b39..f25b8b76df6 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -5054,8 +5054,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
    *  @param  __last1   Another iterator.
    *  @param  __last2   Another iterator.
    *  @param  __result  An iterator pointing to the end of the merged range.
-   *  @return         An iterator pointing to the first element <em>not less
-   *                  than</em> @e val.
+   *  @return   An output iterator equal to @p __result + (__last1 - __first1)
+   *            + (__last2 - __first2).
    *
    *  Merges the ranges @p [__first1,__last1) and @p [__first2,__last2) into
    *  the sorted range @p [__result, __result + (__last1-__first1) +
@@ -5102,8 +5102,8 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
    *  @param  __last2   Another iterator.
    *  @param  __result  An iterator pointing to the end of the merged range.
    *  @param  __comp    A functor to use for comparisons.
-   *  @return         An iterator pointing to the first element "not less
-   *                  than" @e val.
+   *  @return   An output iterator equal to @p __result + (__last1 - __first1)
+   *            + (__last2 - __first2).
    *
    *  Merges the ranges @p [__first1,__last1) and @p [__first2,__last2) into
    *  the sorted range @p [__result, __result + (__last1-__first1) +
diff --git a/libstdc++-v3/include/debug/functions.h b/libstdc++-v3/include/debug/functions.h
index f87838692c6..8c385b87244 100644
--- a/libstdc++-v3/include/debug/functions.h
+++ b/libstdc++-v3/include/debug/functions.h
@@ -219,6 +219,7 @@ namespace __gnu_debug
   // Can't check if an input iterator sequence is sorted, because we
   // can't step through the sequence.
   template<typename _InputIterator>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_sorted_aux(const _InputIterator&, const _InputIterator&,
                        std::input_iterator_tag)
@@ -227,6 +228,7 @@ namespace __gnu_debug
   // Can verify if a forward iterator sequence is in fact sorted using
   // std::__is_sorted
   template<typename _ForwardIterator>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
                        std::forward_iterator_tag)
@@ -245,6 +247,7 @@ namespace __gnu_debug
   // Can't check if an input iterator sequence is sorted, because we can't step
   // through the sequence.
   template<typename _InputIterator, typename _Predicate>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_sorted_aux(const _InputIterator&, const _InputIterator&,
                        _Predicate, std::input_iterator_tag)
@@ -253,6 +256,7 @@ namespace __gnu_debug
   // Can verify if a forward iterator sequence is in fact sorted using
   // std::__is_sorted
   template<typename _ForwardIterator, typename _Predicate>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
                        _Predicate __pred, std::forward_iterator_tag)
@@ -270,31 +274,26 @@ namespace __gnu_debug
 
   // Determine if a sequence is sorted.
   template<typename _InputIterator>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_sorted(const _InputIterator& __first, const _InputIterator& __last)
     {
-      // Verify that the < operator for elements in the sequence is a
-      // StrictWeakOrdering by checking that it is irreflexive.
-      __glibcxx_assert(__first == __last || !(*__first < *__first));
-
       return __check_sorted_aux(__first, __last,
 				std::__iterator_category(__first));
     }
 
   template<typename _InputIterator, typename _Predicate>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_sorted(const _InputIterator& __first, const _InputIterator& __last,
                    _Predicate __pred)
     {
-      // Verify that the predicate is StrictWeakOrdering by checking that it
-      // is irreflexive.
-      __glibcxx_assert(__first == __last || !__pred(*__first, *__first));
-
       return __check_sorted_aux(__first, __last, __pred,
 				std::__iterator_category(__first));
     }
 
   template<typename _InputIterator>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_sorted_set_aux(const _InputIterator& __first,
 			   const _InputIterator& __last,
@@ -302,6 +301,7 @@ namespace __gnu_debug
     { return __check_sorted(__first, __last); }
 
   template<typename _InputIterator>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_sorted_set_aux(const _InputIterator&,
 			   const _InputIterator&,
@@ -309,6 +309,7 @@ namespace __gnu_debug
     { return true; }
 
   template<typename _InputIterator, typename _Predicate>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_sorted_set_aux(const _InputIterator& __first,
 			   const _InputIterator& __last,
@@ -316,6 +317,7 @@ namespace __gnu_debug
     { return __check_sorted(__first, __last, __pred); }
 
   template<typename _InputIterator, typename _Predicate>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_sorted_set_aux(const _InputIterator&,
 			   const _InputIterator&, _Predicate,
@@ -324,6 +326,7 @@ namespace __gnu_debug
 
   // ... special variant used in std::merge, std::includes, std::set_*.
   template<typename _InputIterator1, typename _InputIterator2>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_sorted_set(const _InputIterator1& __first,
 		       const _InputIterator1& __last,
@@ -341,6 +344,7 @@ namespace __gnu_debug
 
   template<typename _InputIterator1, typename _InputIterator2,
 	   typename _Predicate>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_sorted_set(const _InputIterator1& __first,
 		       const _InputIterator1& __last,
@@ -360,6 +364,7 @@ namespace __gnu_debug
   // 270. Binary search requirements overly strict
   // Determine if a sequence is partitioned w.r.t. this element.
   template<typename _ForwardIterator, typename _Tp>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_partitioned_lower(_ForwardIterator __first,
 			      _ForwardIterator __last, const _Tp& __value)
@@ -376,6 +381,7 @@ namespace __gnu_debug
     }
 
   template<typename _ForwardIterator, typename _Tp>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_partitioned_upper(_ForwardIterator __first,
 			      _ForwardIterator __last, const _Tp& __value)
@@ -393,6 +399,7 @@ namespace __gnu_debug
 
   // Determine if a sequence is partitioned w.r.t. this element.
   template<typename _ForwardIterator, typename _Tp, typename _Pred>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_partitioned_lower(_ForwardIterator __first,
 			      _ForwardIterator __last, const _Tp& __value,
@@ -410,6 +417,7 @@ namespace __gnu_debug
     }
 
   template<typename _ForwardIterator, typename _Tp, typename _Pred>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __check_partitioned_upper(_ForwardIterator __first,
 			      _ForwardIterator __last, const _Tp& __value,
@@ -435,35 +443,41 @@ namespace __gnu_debug
 
     template<typename _It,
 	     typename = decltype(__deref<_It>() < __deref<_It>())>
+      _GLIBCXX20_CONSTEXPR
       static bool
       _S_is_valid(_It __it)
       { return !(*__it < *__it); }
 
     // Fallback method if operator doesn't exist.
     template<typename... _Args>
+      _GLIBCXX20_CONSTEXPR
       static bool
       _S_is_valid(_Args...)
       { return true; }
 
     template<typename _It, typename _Pred, typename
 	= decltype(std::declval<_Pred>()(__deref<_It>(), __deref<_It>()))>
+      _GLIBCXX20_CONSTEXPR
       static bool
       _S_is_valid_pred(_It __it, _Pred __pred)
       { return !__pred(*__it, *__it); }
 
     // Fallback method if predicate can't be invoked.
     template<typename... _Args>
+      _GLIBCXX20_CONSTEXPR
       static bool
       _S_is_valid_pred(_Args...)
       { return true; }
   };
 
   template<typename _Iterator>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __is_irreflexive(_Iterator __it)
     { return _Irreflexive_checker::_S_is_valid(__it); }
 
   template<typename _Iterator, typename _Pred>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __is_irreflexive_pred(_Iterator __it, _Pred __pred)
     { return _Irreflexive_checker::_S_is_valid_pred(__it, __pred); }
diff --git a/libstdc++-v3/include/debug/helper_functions.h b/libstdc++-v3/include/debug/helper_functions.h
index 9429bb90a55..16d871e68f4 100644
--- a/libstdc++-v3/include/debug/helper_functions.h
+++ b/libstdc++-v3/include/debug/helper_functions.h
@@ -88,12 +88,14 @@ namespace __gnu_debug
    *	precision.
   */
   template<typename _Iterator>
+    _GLIBCXX_CONSTEXPR
     inline typename _Distance_traits<_Iterator>::__type
     __get_distance(_Iterator __lhs, _Iterator __rhs,
 		   std::random_access_iterator_tag)
     { return std::make_pair(__rhs - __lhs, __dp_exact); }
 
   template<typename _Iterator>
+    _GLIBCXX_CONSTEXPR
     inline typename _Distance_traits<_Iterator>::__type
     __get_distance(_Iterator __lhs, _Iterator __rhs,
 		   std::input_iterator_tag)
@@ -105,6 +107,7 @@ namespace __gnu_debug
     }
 
   template<typename _Iterator>
+    _GLIBCXX_CONSTEXPR
     inline typename _Distance_traits<_Iterator>::__type
     __get_distance(_Iterator __lhs, _Iterator __rhs)
     { return __get_distance(__lhs, __rhs, std::__iterator_category(__lhs)); }
@@ -114,6 +117,13 @@ namespace __gnu_debug
    *  iterators.
   */
   template<typename _Integral>
+    _GLIBCXX_CONSTEXPR
+    inline bool
+    __valid_range_aux(_Integral, _Integral, std::__true_type)
+    { return true; }
+
+  template<typename _Integral>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __valid_range_aux(_Integral, _Integral,
 		      typename _Distance_traits<_Integral>::__type& __dist,
@@ -123,10 +133,35 @@ namespace __gnu_debug
       return true;
     }
 
+  template<typename _InputIterator>
+    _GLIBCXX_CONSTEXPR
+    inline bool
+    __valid_range_aux(_InputIterator __first, _InputIterator __last,
+		      std::input_iterator_tag)
+    { return true; }
+
+  template<typename _InputIterator>
+    _GLIBCXX_CONSTEXPR
+    inline bool
+    __valid_range_aux(_InputIterator __first, _InputIterator __last,
+		      std::random_access_iterator_tag)
+    { return __first <= __last; }
+
   /** We have iterators, so figure out what kind of iterators they are
    *  to see if we can check the range ahead of time.
   */
   template<typename _InputIterator>
+    _GLIBCXX_CONSTEXPR
+    inline bool
+    __valid_range_aux(_InputIterator __first, _InputIterator __last,
+		      std::__false_type)
+    {
+      return __valid_range_aux(__first, __last,
+			       std::__iterator_category(__first));
+    }
+
+  template<typename _InputIterator>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __valid_range_aux(_InputIterator __first, _InputIterator __last,
 		      typename _Distance_traits<_InputIterator>::__type& __dist,
@@ -157,10 +192,16 @@ namespace __gnu_debug
    *  otherwise.
   */
   template<typename _InputIterator>
+    _GLIBCXX20_CONSTEXPR
     inline bool
     __valid_range(_InputIterator __first, _InputIterator __last,
 		  typename _Distance_traits<_InputIterator>::__type& __dist)
     {
+#ifdef __cpp_lib_is_constant_evaluated
+      if (std::is_constant_evaluated())
+	// Detected by the compiler directly.
+	return true;
+#endif
       typedef typename std::__is_integer<_InputIterator>::__type _Integral;
       return __valid_range_aux(__first, __last, __dist, _Integral());
     }
@@ -180,11 +221,17 @@ namespace __gnu_debug
 #endif
 
   template<typename _InputIterator>
+    _GLIBCXX_CONSTEXPR
     inline bool
     __valid_range(_InputIterator __first, _InputIterator __last)
     {
-      typename _Distance_traits<_InputIterator>::__type __dist;
-      return __valid_range(__first, __last, __dist);
+#ifdef __cpp_lib_is_constant_evaluated
+      if (std::is_constant_evaluated())
+	// Detected by the compiler directly.
+	return true;
+#endif
+      typedef typename std::__is_integer<_InputIterator>::__type _Integral;
+      return __valid_range_aux(__first, __last, _Integral());
     }
 
   template<typename _Iterator, typename _Sequence, typename _Category>
@@ -201,6 +248,7 @@ namespace __gnu_debug
 
   // Fallback method, always ok.
   template<typename _InputIterator, typename _Size>
+    _GLIBCXX_CONSTEXPR
     inline bool
     __can_advance(_InputIterator, _Size)
     { return true; }
@@ -218,6 +266,7 @@ namespace __gnu_debug
    *  thanks to the < operator.
    */
   template<typename _Iterator>
+    _GLIBCXX_CONSTEXPR
     inline _Iterator
     __base(_Iterator __it)
     { return __it; }
diff --git a/libstdc++-v3/include/debug/macros.h b/libstdc++-v3/include/debug/macros.h
index b598192cb3e..a6384b21fa4 100644
--- a/libstdc++-v3/include/debug/macros.h
+++ b/libstdc++-v3/include/debug/macros.h
@@ -38,10 +38,20 @@
  * the user error and where the error is reported.
  *
  */
-#define _GLIBCXX_DEBUG_VERIFY_COND_AT(_Cond,_ErrMsg,_File,_Line,_Func)	\
+#if 0 /* defined __cpp_lib_is_constant_evaluated */
+# define _GLIBCXX_DEBUG_VERIFY_COND_AT(_Cond,_ErrMsg,_File,_Line,_Func)	\
+  if (std::is_constant_evaluated())					\
+    /* FIXME: Compilation error here when !_Cond. */			\
+    break;								\
   if (! (_Cond))							\
     __gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func)		\
       ._ErrMsg._M_error()
+#else
+# define _GLIBCXX_DEBUG_VERIFY_COND_AT(_Cond,_ErrMsg,_File,_Line,_Func)	\
+  if (! (_Cond))							\
+    __gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func)		\
+      ._ErrMsg._M_error()
+#endif
 
 #define _GLIBCXX_DEBUG_VERIFY_AT_F(_Cond,_ErrMsg,_File,_Line,_Func)	\
   do									\
@@ -291,9 +301,43 @@ _GLIBCXX_DEBUG_VERIFY(! this->empty(),					\
 		      _M_message(__gnu_debug::__msg_empty)	        \
                       ._M_sequence(*this, "this"))
 
+// Verify that a predicate is irreflexive
+#define __glibcxx_check_irreflexive(_First,_Last)			\
+  _GLIBCXX_DEBUG_VERIFY(_First == _Last || !(*_First < *_First),	\
+			_M_message(__gnu_debug::__msg_irreflexive_ordering) \
+			._M_iterator_value_type(_First, "< operator type"))
+
+#if __cplusplus >= 201103L
+# define __glibcxx_check_irreflexive2(_First,_Last)			\
+  _GLIBCXX_DEBUG_VERIFY(_First == _Last					\
+			|| __gnu_debug::__is_irreflexive(_First),	\
+			_M_message(__gnu_debug::__msg_irreflexive_ordering) \
+			._M_iterator_value_type(_First, "< operator type"))
+#else
+# define __glibcxx_check_irreflexive2(_First,_Last)
+#endif
+
+#define __glibcxx_check_irreflexive_pred(_First,_Last,_Pred)		\
+  _GLIBCXX_DEBUG_VERIFY(_First == _Last || !_Pred(*_First, *_First),	\
+			_M_message(__gnu_debug::__msg_irreflexive_ordering) \
+			._M_instance(_Pred, "functor")			\
+			._M_iterator_value_type(_First, "ordered type"))
+
+#if __cplusplus >= 201103L
+# define __glibcxx_check_irreflexive_pred2(_First,_Last,_Pred)		\
+  _GLIBCXX_DEBUG_VERIFY(_First == _Last					\
+			||__gnu_debug::__is_irreflexive_pred(_First, _Pred), \
+			_M_message(__gnu_debug::__msg_irreflexive_ordering) \
+			._M_instance(_Pred, "functor")			\
+			._M_iterator_value_type(_First, "ordered type"))
+#else
+# define __glibcxx_check_irreflexive_pred2(_First,_Last,_Pred)
+#endif
+
 // Verify that the iterator range [_First, _Last) is sorted
 #define __glibcxx_check_sorted(_First,_Last)				\
 __glibcxx_check_valid_range(_First,_Last);				\
+__glibcxx_check_irreflexive(_First,_Last);				\
  _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(			\
 			__gnu_debug::__base(_First),			\
 			__gnu_debug::__base(_Last)),			\
@@ -305,6 +349,7 @@ __glibcxx_check_valid_range(_First,_Last);				\
     predicate _Pred. */
 #define __glibcxx_check_sorted_pred(_First,_Last,_Pred)			\
 __glibcxx_check_valid_range(_First,_Last);				\
+__glibcxx_check_irreflexive_pred(_First,_Last,_Pred);			\
 _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(			\
 			__gnu_debug::__base(_First),			\
 			__gnu_debug::__base(_Last), _Pred),		\
@@ -423,37 +468,4 @@ _GLIBCXX_DEBUG_VERIFY(_This.get_allocator() == _Other.get_allocator(),	\
 #define __glibcxx_check_string_len(_String,_Len) \
   _GLIBCXX_DEBUG_PEDASSERT(_String != 0 || _Len == 0)
 
-// Verify that a predicate is irreflexive
-#define __glibcxx_check_irreflexive(_First,_Last)			\
-  _GLIBCXX_DEBUG_VERIFY(_First == _Last || !(*_First < *_First),	\
-			_M_message(__gnu_debug::__msg_irreflexive_ordering) \
-			._M_iterator_value_type(_First, "< operator type"))
-
-#if __cplusplus >= 201103L
-# define __glibcxx_check_irreflexive2(_First,_Last)			\
-  _GLIBCXX_DEBUG_VERIFY(_First == _Last					\
-			|| __gnu_debug::__is_irreflexive(_First),	\
-			_M_message(__gnu_debug::__msg_irreflexive_ordering) \
-			._M_iterator_value_type(_First, "< operator type"))
-#else
-# define __glibcxx_check_irreflexive2(_First,_Last)
-#endif
-
-#define __glibcxx_check_irreflexive_pred(_First,_Last,_Pred)		\
-  _GLIBCXX_DEBUG_VERIFY(_First == _Last	|| !_Pred(*_First, *_First),		\
-			_M_message(__gnu_debug::__msg_irreflexive_ordering) \
-			._M_instance(_Pred, "functor")			\
-			._M_iterator_value_type(_First, "ordered type"))
-
-#if __cplusplus >= 201103L
-# define __glibcxx_check_irreflexive_pred2(_First,_Last,_Pred)		\
-  _GLIBCXX_DEBUG_VERIFY(_First == _Last					\
-			||__gnu_debug::__is_irreflexive_pred(_First, _Pred), \
-			_M_message(__gnu_debug::__msg_irreflexive_ordering) \
-			._M_instance(_Pred, "functor")			\
-			._M_iterator_value_type(_First, "ordered type"))
-#else
-# define __glibcxx_check_irreflexive_pred2(_First,_Last,_Pred)
-#endif
-
 #endif
diff --git a/libstdc++-v3/testsuite/25_algorithms/binary_search/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/binary_search/constexpr.cc
index 8406b3d147f..205a96a223b 100644
--- a/libstdc++-v3/testsuite/25_algorithms/binary_search/constexpr.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/binary_search/constexpr.cc
@@ -29,7 +29,7 @@ test()
   const auto out4 = std::binary_search(ca0.begin(), ca0.end(), 5);
 
   const auto out5 = std::binary_search(ca0.begin(), ca0.end(), 5,
-				       std::equal_to<int>());
+				       std::less<int>());
 
   return true;
 }
diff --git a/libstdc++-v3/testsuite/25_algorithms/is_sorted/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/is_sorted/constexpr.cc
index 0be2f5fed62..f549b3d9307 100644
--- a/libstdc++-v3/testsuite/25_algorithms/is_sorted/constexpr.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/is_sorted/constexpr.cc
@@ -26,7 +26,7 @@ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
 constexpr auto outv = std::is_sorted(ca0.begin(), ca0.end());
 
 constexpr auto outw = std::is_sorted(ca0.begin(), ca0.end(),
-				     std::equal_to<int>());
+				     std::less<int>());
 
 constexpr bool
 test()
diff --git a/libstdc++-v3/testsuite/25_algorithms/merge/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/merge/constexpr.cc
index cc8d3755da4..794453dd50c 100644
--- a/libstdc++-v3/testsuite/25_algorithms/merge/constexpr.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/merge/constexpr.cc
@@ -26,7 +26,7 @@ test()
 {
   constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
   constexpr std::array<int, 12> cas{{3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}};
-  constexpr std::array<int, 3> camm{{-4, -5, -6}};
+  constexpr std::array<int, 3> camm{{-6, -5, -4}};
   std::array<int, 24> out0{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
 
   const auto outdd = std::merge(ca0.begin(), ca0.end(),
@@ -34,7 +34,7 @@ test()
 
   const auto outee = std::merge(ca0.begin(), ca0.end(),
 				camm.begin(), camm.end(), out0.begin(),
-				[](int i, int j){ return i < -j; });
+				[](int i, int j){ return i < j; });
 
   return true;
 }

  reply	other threads:[~2019-09-27 16:24 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-19 20:28 François Dumont
2019-09-20  5:08 ` François Dumont
2019-09-25 20:40   ` François Dumont
2019-09-27 11:24   ` Jonathan Wakely
2019-10-01 20:05     ` François Dumont
2019-10-10 20:03       ` Jonathan Wakely
2019-10-16 20:22         ` François Dumont
2019-09-27 12:11 ` Jonathan Wakely
2019-09-27 16:24   ` François Dumont [this message]
2019-09-27 16:45     ` Jonathan Wakely
2019-09-28 21:12       ` [PATCH] Fix algo constexpr tests in Debug mode François Dumont
2019-09-30  9:03         ` Jonathan Wakely
2019-09-30 20:21           ` François Dumont
2019-10-01 11:21             ` Jonathan Wakely
2019-10-23 15:26         ` Jonathan Wakely

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e04cfab3-f80f-f401-b5ec-448f97c69078@gmail.com \
    --to=frs.dumont@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jwakely@redhat.com \
    --cc=libstdc++@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).