This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [ PATCH ] C++20 <span>


On 05/09/19 12:27 +0100, Jonathan Wakely wrote:
On 04/09/19 18:47 -0400, JeanHeyd Meneide wrote:
   Thank you for the thorough review!

On Tue, Sep 3, 2019 at 9:31 AM Jonathan Wakely <jwakely@redhat.com> wrote:
It looks like__adl_begin and __adl_end should be guarded by #ifdef
_GLIBCXX_P1394 because they're not needed otherwise.

   I'm absolutely going to need it for the bit data structures (and
in tuning up other parts of the library). It will also be important
for things that need to behave nicely when working with things needing
[range.access] internally in libstdc++,
while we wait for the cmcstl2 implementation. I did gate
__adl_to_address behind p1394, though, because that is definitely
specific to that paper (and its friend, p1474).

OK, then it's fine as is, thanks.

+/** @file span
+ *  This is a Standard C++ Library header.
+ */
+
+//
+// P0122 span library
+// Contributed by ThePhD
+//
+
+#ifndef _GLIBCXX_SPAN
+#define _GLIBCXX_SPAN 1
+
+#pragma GCC system_header
+
+#if __cplusplus > 201703L
+
+#include <cstddef>

This header isn't needed. <bits/c++config.h> defines std::size_t and
std::ptrdiff_t, and every libstdc++ header should include
<bits/c++config.h> already. Not including <cstddef> is a minor
optimisation for compile time, because we don't need to open <cstddef>
and <stddef.h>.

+    template<typename _Tp, size_t _Num>
+      inline constexpr bool
+      __is_std_array_v<_GLIBCXX_STD_C::array<_Tp, _Num>> = true;
+
+#ifdef _GLIBCXX_DEBUG
+    template<typename _Tp, size_t _Num>
+      inline constexpr bool
+      __is_std_array_v<std::__debug::array<_Tp, _Num>> = true;
+#endif // debug/array
+
+    template<size_t _Extent>
+      class __extent_storage
+      {
+      public:
+
+        constexpr
+        __extent_storage() noexcept = default;

Something else I forgot to mention (which I'll add to the coding
conventions documentation) is that we use TABs for indentation at the
start of lines. Tabstop should be set to 8, so anything indented by 8
chars or more should use TABs. Anything indented by fewer than 8 chars
just uses spaces.

+
+        constexpr
+        __extent_storage(size_t) noexcept
+        {}
+
+        static constexpr size_t
+        _M_extent() noexcept
+        { return _Extent; }
+      };
+
+    template<>
+      class __extent_storage<static_cast<size_t>(-1)>
+      {
+      public:
+
+        constexpr
+        __extent_storage() noexcept : _M_extent_value(0){};
+
+        constexpr
+        __extent_storage(size_t __extent) noexcept
+        : _M_extent_value(__extent)
+        {}
+
+        constexpr size_t
+        _M_extent() const noexcept
+        { return this->_M_extent_value; }
+
+      private:
+        size_t _M_extent_value;
+      };
+
+  } // namespace __detail
+
+  template<typename _Type, size_t _Extent = dynamic_extent>
+    class span : private __detail::__extent_storage<_Extent>
+    {
+    public:
+      // member types
+      using value_type             = remove_cv_t<_Type>;
+      using element_type           = _Type;
+      using index_type             = size_t;
+      using reference              = element_type&;
+      using const_reference        = const element_type&;
+      using pointer                = _Type*;
+      using const_pointer          = const _Type*;
+      using iterator               = __gnu_cxx::__normal_iterator<pointer, span>;
+      using const_iterator         = __gnu_cxx::__normal_iterator<const_pointer, span>;
+      using reverse_iterator       = ::std::reverse_iterator<iterator>;
+      using const_reverse_iterator = ::std::reverse_iterator<const_iterator>;
+      using difference_type        = ptrdiff_t;
+      // Official wording has no size_type -- why??
+      // using size_type = size_t;
+
+      // member constants
+      static inline constexpr size_t extent = _Extent;
+
+    private:
+      using __base_t = __detail::__extent_storage<extent>;
+
+    public:
+      // constructors
+      template <typename _Dummy = _Type, enable_if_t<is_same_v<_Dummy, _Type> && (_Extent == dynamic_extent || _Extent == 0)>* = nullptr>

This line is too long, it needs to be split before 80 columns.

+        constexpr span() noexcept : __base_t(0), _M_ptr(nullptr)
+        {}
+
+      constexpr
+      span(const span&) noexcept = default;
+
+      template<size_t _ArrayExtent,
+        enable_if_t<
+          (_Extent == dynamic_extent || _ArrayExtent == _Extent) &&

N.B. line breaks should come before logical operators like && e.g.

    foo
    && bar

Not:

    foo &&
    bar

The rationale for this is to make it easy to see the operator. You can
look at the start of  the line (at a predictable, easily findable
position) instead of having to look at the right hand side to see if
it's a && or || operator.


+      template<typename _Container,
+        enable_if_t<
+          (_Extent == dynamic_extent) &&
+          !is_same_v<remove_cvref_t<_Container>, span> &&
+          !__detail::__is_std_array_v<remove_cvref_t<_Container>> &&
+          !is_array_v<remove_cvref_t<_Container>> &&

Here's a good example where the && operators are all at different
columns, but if you put line breaks before the operator it looks like:

        (_Extent == dynamic_extent)
        && !is_same_v<remove_cvref_t<_Container>, span>
        && !__detail::__is_std_array_v<remove_cvref_t<_Container>>
        && !is_array_v<remove_cvref_t<_Container>>
        && ...

This is easier to see that it's a series of AND conditions with a
quick glance.

As discussed on IRC the new XFAIL tests need some adjustment. The
attached patch changes the whitespace as discussed above, and fixes
the tests.

Our convention for XFAIL tests is to call them foo_neg.cc (not
fail.foo.cc like libc++ uses).

The attached patch is what I've tested and committed to trunk - thanks
very much!

I'll make some additional fixes (e.g. LWG 3103) and update the docs
later today.

Here's the follow-up patch.

Tested x86_64-linux, committed to trunk.


commit 8b9507a5e5a4f98cace57780d638f24dccef5756
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Sep 5 13:26:14 2019 +0100

    Improve precondition checks for std::span
    
            * doc/xml/manual/status_cxx2020.xml: Update status for P0122R7 and
            P1024R3. Remove entry for P0920R2.
            * include/std/span  (__cpp_lib_span): Change value.
            (__extent_storage, __extent_storage<dynamic_extent>): Remove default
            constructor.
            (span): Replace __extent_storage base class with data member.
            (span::_S_subspan_extent): New function.
            (span::empty()): Add nodiscard attribute.
            (span::front, span::back, span::operator[]): Check preconditions.
            (span::first, span::last, span::subspan): Add noexcept. Improve
            precondition checks (LWG 3103).
            (get): Remove redundant condition from static_assert.
            (tuple_element<I, span<T, E>>): Fix static_assert message and simplify.
            (as_writable_bytes): Add inline specifier.
            * include/std/version (__cpp_lib_span): Change value.
            * testsuite/23_containers/span/back_neg.cc: Remove stray semi-colon.
            * testsuite/23_containers/span/front_neg.cc: Likewise.
            * testsuite/23_containers/span/index_op_neg.cc: Likewise.
            * testsuite/23_containers/span/last_neg.cc: Improve test.
            * testsuite/23_containers/span/subspan_neg.cc: Likewise.
            * testsuite/23_containers/span/1.cc: New test.
            * testsuite/23_containers/span/2.cc: New test.
            * testsuite/23_containers/span/back_assert_neg.cc: New test.
            * testsuite/23_containers/span/first_2_assert_neg.cc: New test.
            * testsuite/23_containers/span/first_assert_neg.cc: New test.
            * testsuite/23_containers/span/first_neg.cc: New test.
            * testsuite/23_containers/span/front_assert_neg.cc: New test.
            * testsuite/23_containers/span/index_op_assert_neg.cc: New test.
            * testsuite/23_containers/span/last_2_assert_neg.cc: New test.
            * testsuite/23_containers/span/last_assert_neg.cc: New test.
            * testsuite/23_containers/span/subspan_2_assert_neg.cc: New test.
            * testsuite/23_containers/span/subspan_3_assert_neg.cc: New test.
            * testsuite/23_containers/span/subspan_4_assert_neg.cc: New test.
            * testsuite/23_containers/span/subspan_5_assert_neg.cc: New test.
            * testsuite/23_containers/span/subspan_6_assert_neg.cc: New test.
            * testsuite/23_containers/span/subspan_assert_neg.cc: New test.

diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2020.xml b/libstdc++-v3/doc/xml/manual/status_cxx2020.xml
index 3a5de38ad22..ffd73aefc96 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2020.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2020.xml
@@ -237,15 +237,14 @@ Feature-testing recommendations for C++</link>.
     </row>
 
     <row>
-      <?dbhtml bgcolor="#C8B0B0" ?>
       <entry>  <code>&lt;span&gt;</code> </entry>
       <entry>
         <link xmlns:xlink="http://www.w3.org/1999/xlink"; xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0122r7.pdf";>
 	P0122R7
 	</link>
       </entry>
-      <entry align="center"> </entry>
-      <entry />
+      <entry align="center"> 10.1 </entry>
+      <entry> <code>__cpp_lib_span &gt;= 201803L</code> </entry>
     </row>
 
     <row>
@@ -1111,7 +1110,6 @@ Feature-testing recommendations for C++</link>.
     </row>
 
     <row>
-      <?dbhtml bgcolor="#C8B0B0" ?>
       <entry>
         Usability Enhancements for <classname>std::span</classname>
       </entry>
@@ -1120,20 +1118,8 @@ Feature-testing recommendations for C++</link>.
         P1024R3
 	</link>
       </entry>
-      <entry align="center"> </entry>
-      <entry />
-    </row>
-
-    <row>
-      <?dbhtml bgcolor="#C8B0B0" ?>
-      <entry> Precalculated hash values in lookup </entry>
-      <entry>
-        <link xmlns:xlink="http://www.w3.org/1999/xlink"; xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0920r2.html";>
-        P0920R2
-	</link>
-      </entry>
-      <entry align="center"> </entry>
-      <entry />
+      <entry align="center"> 10.1 </entry>
+      <entry> <code>__cpp_lib_span &gt;= 201902L</code> </entry>
     </row>
 
     <row>
diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span
index 4ce2f31a131..95d778b104b 100644
--- a/libstdc++-v3/include/std/span
+++ b/libstdc++-v3/include/std/span
@@ -49,9 +49,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-// FIXME: they forgot this feature test macro
-// get on someone's back about it in Belfast!!!
-#define __cpp_lib_span 201911
+#define __cpp_lib_span 201902L
 
   inline constexpr size_t dynamic_extent = static_cast<size_t>(-1);
 
@@ -78,9 +76,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       class __extent_storage
       {
       public:
-	constexpr
-	__extent_storage() noexcept = default;
-
 	constexpr
 	__extent_storage(size_t) noexcept
 	{ }
@@ -91,13 +86,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       };
 
     template<>
-      class __extent_storage<static_cast<size_t>(-1)>
+      class __extent_storage<dynamic_extent>
       {
       public:
-	constexpr
-	__extent_storage() noexcept : _M_extent_value(0)
-	{ };
-
 	constexpr
 	__extent_storage(size_t __extent) noexcept
 	: _M_extent_value(__extent)
@@ -114,8 +105,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   } // namespace __detail
 
   template<typename _Type, size_t _Extent = dynamic_extent>
-    class span : private __detail::__extent_storage<_Extent>
+    class span
     {
+      template<size_t _Offset, size_t _Count>
+	static constexpr size_t
+	_S_subspan_extent()
+	{
+	  if constexpr (_Count != dynamic_extent)
+	    return _Count;
+	  else if constexpr (extent != dynamic_extent)
+	    return _Extent - _Offset;
+	  else
+	    return dynamic_extent;
+	}
+
     public:
       // member types
       using value_type             = remove_cv_t<_Type>;
@@ -138,17 +141,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // member constants
       static inline constexpr size_t extent = _Extent;
 
-    private:
-      using __base_t = __detail::__extent_storage<extent>;
-
-    public:
       // constructors
 
       template <typename _Dummy = _Type,
 		enable_if_t<is_same_v<_Dummy, _Type>
 		  && (_Extent == dynamic_extent || _Extent == 0)>* = nullptr>
 	constexpr
-	span() noexcept : __base_t(0), _M_ptr(nullptr)
+	span() noexcept : _M_extent(0), _M_ptr(nullptr)
 	{ }
 
       constexpr
@@ -234,7 +233,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	constexpr
 	span(_ContiguousIterator __first, index_type __count)
 	noexcept(noexcept(::std::__adl_to_address(__first)))
-	: __base_t(__count), _M_ptr(::std::__adl_to_address(__first))
+	: _M_extent(__count), _M_ptr(::std::__adl_to_address(__first))
 	{ __glibcxx_assert(_Extent == dynamic_extent || __count == _Extent); }
 
 #else
@@ -276,7 +275,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       constexpr
       span(pointer __first, index_type __count) noexcept
-      : __base_t(__count), _M_ptr(static_cast<pointer>(__first))
+      : _M_extent(__count), _M_ptr(static_cast<pointer>(__first))
       { __glibcxx_assert(_Extent == dynamic_extent || __count == _Extent); }
 
       constexpr
@@ -290,41 +289,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       constexpr span&
       operator=(const span&) noexcept = default;
 
-      // observers: element access
+      // observers
+
+      constexpr index_type
+      size() const noexcept
+      { return this->_M_extent._M_extent(); }
+
+      constexpr index_type
+      size_bytes() const noexcept
+      { return this->_M_extent._M_extent() * sizeof(element_type); }
+
+      [[nodiscard]] constexpr bool
+      empty() const noexcept
+      { return size() == 0; }
+
+      // element access
 
       constexpr reference
       front() const noexcept
-      { return *this->begin(); }
+      {
+	static_assert(extent != 0);
+	__glibcxx_assert(!empty());
+	return *this->_M_ptr;
+      }
 
       constexpr reference
       back() const noexcept
       {
-	iterator __it = this->end();
-	--__it;
-	return *__it;
+	static_assert(extent != 0);
+	__glibcxx_assert(!empty());
+	return *(this->_M_ptr + (size() - 1));
       }
 
       constexpr reference
       operator[](index_type __idx) const noexcept
-      { return *(this->_M_ptr + __idx); }
+      {
+	static_assert(extent != 0);
+	__glibcxx_assert(__idx < size());
+	return *(this->_M_ptr + __idx);
+      }
 
       constexpr pointer
       data() const noexcept
       { return this->_M_ptr; }
 
-      constexpr index_type
-      size() const noexcept
-      { return this->__base_t::_M_extent(); }
+      // iterator support
 
-      constexpr index_type
-      size_bytes() const noexcept
-      { return this->__base_t::_M_extent() * sizeof(element_type); }
-
-      constexpr bool
-      empty() const noexcept
-      { return size() == 0; }
-
-      // observers: iterator support
       constexpr iterator
       begin() const noexcept
       { return iterator(this->_M_ptr); }
@@ -357,70 +367,85 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       crend() const noexcept
       { return const_reverse_iterator(this->cbegin()); }
 
-      // observers: subranges
+      // subviews
+
       template<size_t _Count>
 	constexpr span<element_type, _Count>
-	first() const
+	first() const noexcept
 	{
-	  __glibcxx_assert(_Count < size());
+	  if constexpr (_Extent == dynamic_extent)
+	    __glibcxx_assert(_Count <= size());
+	  else
+	    static_assert(_Count <= extent);
 	  return { this->data(), _Count };
 	}
 
       constexpr span<element_type, dynamic_extent>
-      first(index_type __count) const
+      first(index_type __count) const noexcept
       {
-	__glibcxx_assert(__count < size());
+	__glibcxx_assert(__count <= size());
 	return { this->data(), __count };
       }
 
       template<size_t _Count>
 	constexpr span<element_type, _Count>
-	last() const
+	last() const noexcept
 	{
-	  static_assert(_Count == dynamic_extent ||
-			  _Extent == dynamic_extent || _Count <= _Extent,
-	    "Count or Extent are dynamic, "
-	    "or the Count is less than the static extent");
-	  __glibcxx_assert(_Count <= size());
+	  if constexpr (_Extent == dynamic_extent)
+	    __glibcxx_assert(_Count <= size());
+	  else
+	    static_assert(_Count <= extent);
 	  return { this->data() + (this->size() - _Count), _Count };
 	}
 
       constexpr span<element_type, dynamic_extent>
-      last(index_type __count) const
+      last(index_type __count) const noexcept
       {
-	__glibcxx_assert(__count < size());
-	index_type __offset = (this->size() - __count);
-	return { this->data() + __offset, __count };
+	__glibcxx_assert(__count <= size());
+	return { this->data() + (this->size() - __count), __count };
       }
 
       template<size_t _Offset, size_t _Count = dynamic_extent>
 	constexpr auto
-	subspan() const
+	subspan() const noexcept
+	-> span<element_type, _S_subspan_extent<_Offset, _Count>()>
 	{
-	  static_assert(_Count == dynamic_extent ||
-			  _Extent == dynamic_extent ||
-			  (_Offset + _Count) <= _Extent,
-	    "Count or Extent are dynamic, "
-	    "or the Count + Offset is less than the static extent");
-	  constexpr size_t __span_extent =
-	    (_Count != dynamic_extent
-		? _Count
-		: (_Extent != dynamic_extent ? _Extent - _Offset
-						    : dynamic_extent));
-	  using __span_t = span<element_type, __span_extent>;
-	  if constexpr(_Count != dynamic_extent)
+	  if constexpr (_Extent == dynamic_extent)
+	    __glibcxx_assert(_Offset <= size());
+	  else
+	    static_assert(_Offset <= extent);
+
+	  if constexpr (_Count == dynamic_extent)
+	    return { this->data() + _Offset, this->size() - _Offset };
+	  else
 	    {
-	      __glibcxx_assert((_Offset + _Count) < size());
+	      if constexpr (_Extent == dynamic_extent)
+		{
+		  __glibcxx_assert(_Count <= size());
+		  __glibcxx_assert(_Count <= (size() - _Offset));
+		}
+	      else
+		{
+		  static_assert(_Count <= extent);
+		  static_assert(_Count <= (extent - _Offset));
+		}
+	      return { this->data() + _Offset, _Count };
 	    }
-	  return __span_t(this->data() + _Offset,
-	    (_Count == dynamic_extent ? this->size() - _Offset : _Count));
 	}
 
       constexpr span<element_type, dynamic_extent>
       subspan(index_type __offset, index_type __count = dynamic_extent) const
+      noexcept
       {
-	return {this->data() + __offset,
-	  __count == dynamic_extent ? this->size() - __offset : __count};
+	__glibcxx_assert(__offset <= size());
+	if (__count == dynamic_extent)
+	  __count = this->size() - __offset;
+	else
+	  {
+	    __glibcxx_assert(__count <= size());
+	    __glibcxx_assert(__offset + __count <= size());
+	  }
+	return {this->data() + __offset, __count};
       }
 
       // observers: range helpers
@@ -434,51 +459,54 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { return __sp.end(); }
 
     private:
+      [[no_unique_address]] __detail::__extent_storage<extent> _M_extent;
       pointer _M_ptr;
     };
 
   // deduction guides
   template<typename _Type, size_t _ArrayExtent>
-    span(_Type(&)[_ArrayExtent])->span<_Type, _ArrayExtent>;
+    span(_Type(&)[_ArrayExtent]) -> span<_Type, _ArrayExtent>;
 
   template<typename _Type, size_t _ArrayExtent>
-    span(array<_Type, _ArrayExtent>&)->span<_Type, _ArrayExtent>;
+    span(array<_Type, _ArrayExtent>&) -> span<_Type, _ArrayExtent>;
 
   template<typename _Type, size_t _ArrayExtent>
     span(const array<_Type, _ArrayExtent>&)
-      ->span<const _Type, _ArrayExtent>;
+      -> span<const _Type, _ArrayExtent>;
 
 #if defined(_GLIBCXX_P1394) && _GLIBCXX_P1394
 
   template<typename _ContiguousIterator, typename _Sentinel>
     span(_ContiguousIterator, _Sentinel)
-      ->span<remove_reference_t<
+      -> span<remove_reference_t<
 	typename iterator_traits<_ContiguousIterator>::reference>>;
 
   template<typename _Range>
     span(_Range &&)
-      ->span<remove_reference_t<typename iterator_traits<decltype(
-	::std::__adl_begin(::std::declval<_Range&>()))>::reference>>;
+      -> span<remove_reference_t<typename iterator_traits<
+	  decltype(std::__adl_begin(::std::declval<_Range&>()))>::reference>>;
 
 #else
 
   template<typename _Container>
-    span(_Container&)->span<typename _Container::value_type>;
+    span(_Container&) -> span<typename _Container::value_type>;
 
   template<typename _Container>
-    span(const _Container&)->span<const typename _Container::value_type>;
+    span(const _Container&) -> span<const typename _Container::value_type>;
 
 #endif // P1394
 
   template<typename _Type, size_t _Extent>
+    inline
     span<const byte, _Extent == dynamic_extent
 	? dynamic_extent : _Extent * sizeof(_Type)>
-    inline as_bytes(span<_Type, _Extent> __sp) noexcept
+    as_bytes(span<_Type, _Extent> __sp) noexcept
     {
       return {reinterpret_cast<const byte*>(__sp.data()), __sp.size_bytes()};
     }
 
   template<typename _Type, size_t _Extent>
+    inline
     span<byte, _Extent == dynamic_extent
        ? dynamic_extent : _Extent * sizeof(_Type)>
     as_writable_bytes(span<_Type, _Extent> __sp) noexcept
@@ -491,9 +519,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     constexpr _Type&
     get(span<_Type, _Extent> __sp) noexcept
     {
-      static_assert(_Extent != dynamic_extent
-	&& (_Extent > 0) && (_Index < _Extent),
-	"std::get can only be used with a span of non-dynamic (fixed) extent");
+      static_assert(_Extent != dynamic_extent && _Index < _Extent,
+	"get<I> can only be used with a span of non-dynamic (fixed) extent");
       return __sp[_Index];
     }
 
@@ -508,10 +535,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<size_t _Index, typename _Type, size_t _Extent>
     struct tuple_element<_Index, span<_Type, _Extent>>
     {
-      static_assert(_Extent != dynamic_extent, "tuple_size can only "
+      static_assert(_Extent != dynamic_extent, "tuple_element can only "
 	"be used with a span of non-dynamic (fixed) extent");
       static_assert(_Index < _Extent, "Index is less than Extent");
-      using type = typename span<_Type, _Extent>::element_type;
+      using type = _Type;
     };
 
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index 4341c9f0c1b..7625d397a0d 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -166,10 +166,8 @@
 #endif
 #define __cpp_lib_list_remove_return_type 201806L
 #define __cpp_lib_math_constants 201907L
+#define __cpp_lib_span 201902L
 #define __cpp_lib_to_array 201907L
-// FIXME: they forgot this feature test macro
-// get on someone's back about it in Belfast!!!
-#define __cpp_lib_span 201911
 #endif // C++2a
 #endif // C++17
 #endif // C++14
diff --git a/libstdc++-v3/testsuite/23_containers/span/1.cc b/libstdc++-v3/testsuite/23_containers/span/1.cc
new file mode 100644
index 00000000000..c31d8d400ce
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/1.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <span>
+
+#ifndef __cpp_lib_span
+# error "Feature-test macro for span missing in <span>"
+#elif __cpp_lib_span != 201902L
+# error "Feature-test macro for span has wrong value in <span>"
+#endif
diff --git a/libstdc++-v3/testsuite/23_containers/span/2.cc b/libstdc++-v3/testsuite/23_containers/span/2.cc
new file mode 100644
index 00000000000..1870ba16973
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/2.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <version>
+
+#ifndef __cpp_lib_span
+# error "Feature-test macro for span missing in <version>"
+#elif __cpp_lib_span != 201902L
+# error "Feature-test macro for span has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/23_containers/span/back_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/back_assert_neg.cc
new file mode 100644
index 00000000000..0b8fc672a20
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/back_assert_neg.cc
@@ -0,0 +1,28 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { xfail c++2a } }
+
+#define _GLIBCXX_ASSERTIONS
+#include <span>
+
+int main()
+{
+  std::span<int, std::dynamic_extent> s;
+  s.back();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/span/back_neg.cc b/libstdc++-v3/testsuite/23_containers/span/back_neg.cc
new file mode 100644
index 00000000000..b1bb10f40d1
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/back_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <span>
+
+void
+test01()
+{
+  std::span<int, 0> s;
+  s.back(); // { dg-error "here" }
+}
+// { dg-error "static assertion failed" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/first_2_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/first_2_assert_neg.cc
new file mode 100644
index 00000000000..fd9c9204d1e
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/first_2_assert_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { xfail c++2a } }
+
+#define _GLIBCXX_ASSERTIONS
+#include <span>
+
+int main()
+{
+  int a[4];
+  std::span<int, std::dynamic_extent> s(a);
+  s.first(5);
+}
diff --git a/libstdc++-v3/testsuite/23_containers/span/first_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/first_assert_neg.cc
new file mode 100644
index 00000000000..94f1f03a64a
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/first_assert_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { xfail c++2a } }
+
+#define _GLIBCXX_ASSERTIONS
+#include <span>
+
+int main()
+{
+  int a[4];
+  std::span<int, std::dynamic_extent> s(a);
+  s.first<5>();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/span/first_neg.cc b/libstdc++-v3/testsuite/23_containers/span/first_neg.cc
new file mode 100644
index 00000000000..42729347d33
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/first_neg.cc
@@ -0,0 +1,30 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <span>
+
+void
+test01()
+{
+  int a[4];
+  std::span<int, 4> s(a);
+  s.first<5>(); // { dg-error "here" }
+}
+// { dg-error "static assertion failed" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/front_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/front_assert_neg.cc
new file mode 100644
index 00000000000..516bf2a2dcb
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/front_assert_neg.cc
@@ -0,0 +1,28 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { xfail c++2a } }
+
+#define _GLIBCXX_ASSERTIONS
+#include <span>
+
+int main()
+{
+  std::span<int, std::dynamic_extent> s;
+  s.front();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/span/front_neg.cc b/libstdc++-v3/testsuite/23_containers/span/front_neg.cc
new file mode 100644
index 00000000000..4c2b6e39c70
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/front_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <span>
+
+void
+test01()
+{
+  std::span<int, 0> s;
+  s.front(); // { dg-error "here" }
+}
+// { dg-error "static assertion failed" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/index_op_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/index_op_assert_neg.cc
new file mode 100644
index 00000000000..4109c4cdc7a
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/index_op_assert_neg.cc
@@ -0,0 +1,28 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { xfail c++2a } }
+
+#define _GLIBCXX_ASSERTIONS
+#include <span>
+
+int main()
+{
+  std::span<int, std::dynamic_extent> s;
+  s[99];
+}
diff --git a/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc b/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc
new file mode 100644
index 00000000000..5bd1e11dda0
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/index_op_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <span>
+
+void
+test01()
+{
+  std::span<int, 0> s;
+  s[99]; // { dg-error "here" }
+}
+// { dg-error "static assertion failed" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/last_2_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/last_2_assert_neg.cc
new file mode 100644
index 00000000000..1cc060f4735
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/last_2_assert_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { xfail c++2a } }
+
+#define _GLIBCXX_ASSERTIONS
+#include <span>
+
+int main()
+{
+  int a[4];
+  std::span<int, std::dynamic_extent> s(a);
+  s.last(5);
+}
diff --git a/libstdc++-v3/testsuite/23_containers/span/last_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/last_assert_neg.cc
new file mode 100644
index 00000000000..31b6cc0816f
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/last_assert_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { xfail c++2a } }
+
+#define _GLIBCXX_ASSERTIONS
+#include <span>
+
+int main()
+{
+  int a[4];
+  std::span<int, std::dynamic_extent> s(a);
+  s.last<5>();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/span/last_neg.cc b/libstdc++-v3/testsuite/23_containers/span/last_neg.cc
index 8f0145f7012..ac77dbe4438 100644
--- a/libstdc++-v3/testsuite/23_containers/span/last_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/last_neg.cc
@@ -15,15 +15,16 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=c++2a" }
+// { dg-options "-std=gnu++2a" }
 // { dg-do compile { target c++2a } }
 
 #include <span>
 
-int
-main()
+void
+test01()
 {
-  std::span<int, 2> myspan(nullptr, 2);
-  myspan.last<3>(); // { dg-error "here" }
+  int a[2];
+  std::span<int, 2> s(a);
+  s.last<3>(); // { dg-error "here" }
 }
 // { dg-error "static assertion failed" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_2_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_2_assert_neg.cc
new file mode 100644
index 00000000000..355a71c9d9d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/subspan_2_assert_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { xfail c++2a } }
+
+#define _GLIBCXX_ASSERTIONS
+#include <span>
+
+int main()
+{
+  int a[4];
+  std::span<int, std::dynamic_extent> s(a);
+  s.subspan<2, 5>();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_3_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_3_assert_neg.cc
new file mode 100644
index 00000000000..bdf4abad2c6
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/subspan_3_assert_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { xfail c++2a } }
+
+#define _GLIBCXX_ASSERTIONS
+#include <span>
+
+int main()
+{
+  int a[4];
+  std::span<int, std::dynamic_extent> s(a);
+  s.subspan<2, 3>();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_4_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_4_assert_neg.cc
new file mode 100644
index 00000000000..37ebed038fa
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/subspan_4_assert_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { xfail c++2a } }
+
+#define _GLIBCXX_ASSERTIONS
+#include <span>
+
+int main()
+{
+  int a[4];
+  std::span<int, std::dynamic_extent> s(a);
+  s.subspan(5, 0);
+}
diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_5_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_5_assert_neg.cc
new file mode 100644
index 00000000000..615ea0ba559
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/subspan_5_assert_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { xfail c++2a } }
+
+#define _GLIBCXX_ASSERTIONS
+#include <span>
+
+int main()
+{
+  int a[4];
+  std::span<int, std::dynamic_extent> s(a);
+  s.subspan(2, 5);
+}
diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_6_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_6_assert_neg.cc
new file mode 100644
index 00000000000..db5f427b35f
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/subspan_6_assert_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { xfail c++2a } }
+
+#define _GLIBCXX_ASSERTIONS
+#include <span>
+
+int main()
+{
+  int a[4];
+  std::span<int, std::dynamic_extent> s(a);
+  s.subspan(2, 3);
+}
diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_assert_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_assert_neg.cc
new file mode 100644
index 00000000000..d120d436c23
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/subspan_assert_neg.cc
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { xfail c++2a } }
+
+#define _GLIBCXX_ASSERTIONS
+#include <span>
+
+int main()
+{
+  int a[4];
+  std::span<int, std::dynamic_extent> s(a);
+  s.subspan<5, 0>();
+}
diff --git a/libstdc++-v3/testsuite/23_containers/span/subspan_neg.cc b/libstdc++-v3/testsuite/23_containers/span/subspan_neg.cc
index 5ecbff937cc..70fcda6e91a 100644
--- a/libstdc++-v3/testsuite/23_containers/span/subspan_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/span/subspan_neg.cc
@@ -15,15 +15,33 @@
 // with this library; see the file COPYING3.  If not see
 // <http://www.gnu.org/licenses/>.
 
-// { dg-options "-std=c++2a" }
+// { dg-options "-std=gnu++2a" }
 // { dg-do compile { target c++2a } }
 
 #include <span>
 
-int
-main()
+void
+test01()
 {
-  std::span<int, 2> myspan(nullptr, 2);
-  myspan.subspan<3, 1>(); // { dg-error "here" }
+  int a[4];
+  std::span<int, 4> s(a);
+  s.subspan<5, 0>(); // { dg-error "here" }
 }
+
+void
+test02()
+{
+  int a[4];
+  std::span<int, 4> s(a);
+  s.subspan<3, 5>(); // { dg-error "here" }
+}
+
+void
+test03()
+{
+  int a[4];
+  std::span<int, 4> s(a);
+  s.subspan<3, 2>(); // { dg-error "here" }
+}
+
 // { dg-error "static assertion failed" "" { target *-*-* } 0 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]