[libcxx-commits] [libcxx] 0a0e0af - [libc++] span: Fix incorrect static asserts
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Feb 14 05:33:11 PST 2020
Author: Louis Dionne
Date: 2020-02-14T14:32:41+01:00
New Revision: 0a0e0afaa0249a07b5d1609c433e991c8d982a73
URL: https://github.com/llvm/llvm-project/commit/0a0e0afaa0249a07b5d1609c433e991c8d982a73
DIFF: https://github.com/llvm/llvm-project/commit/0a0e0afaa0249a07b5d1609c433e991c8d982a73.diff
LOG: [libc++] span: Fix incorrect static asserts
The static asserts in span<T, N>::front() and span<T, N>::back() are
incorrect as they may be triggered from valid code due to evaluation
of a never taken branch:
span<int, 0> foo;
if (!foo.empty()) {
auto x = foo.front();
}
The problem is that the branch is always evaluated by the compiler,
creating invalid compile errors for span<T, 0>.
Thanks to Michael Schellenberger Costa for the patch.
Differential Revision: https://reviews.llvm.org/D71995
Added:
Modified:
libcxx/include/span
libcxx/test/std/containers/views/span.elem/back.pass.cpp
libcxx/test/std/containers/views/span.elem/front.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/span b/libcxx/include/span
index 82bcbff402b1..1fe1496530e9 100644
--- a/libcxx/include/span
+++ b/libcxx/include/span
@@ -307,13 +307,13 @@ public:
_LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept
{
- static_assert(_Extent > 0, "span<T,N>[].front() on empty span");
+ _LIBCPP_ASSERT(!empty(), "span<T, N>::front() on empty span");
return __data[0];
}
_LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept
{
- static_assert(_Extent > 0, "span<T,N>[].back() on empty span");
+ _LIBCPP_ASSERT(!empty(), "span<T, N>::back() on empty span");
return __data[size()-1];
}
diff --git a/libcxx/test/std/containers/views/span.elem/back.pass.cpp b/libcxx/test/std/containers/views/span.elem/back.pass.cpp
index f2c0cf60dbe8..5bb9631aa90b 100644
--- a/libcxx/test/std/containers/views/span.elem/back.pass.cpp
+++ b/libcxx/test/std/containers/views/span.elem/back.pass.cpp
@@ -30,7 +30,6 @@ constexpr bool testConstexprSpan(Span sp)
return std::addressof(sp.back()) == sp.data() + sp.size() - 1;
}
-
template <typename Span>
void testRuntimeSpan(Span sp)
{
@@ -38,6 +37,12 @@ void testRuntimeSpan(Span sp)
assert(std::addressof(sp.back()) == sp.data() + sp.size() - 1);
}
+template <typename Span>
+void testEmptySpan(Span sp)
+{
+ if (!sp.empty())
+ [[maybe_unused]] auto res = sp.back();
+}
struct A{};
constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
@@ -71,5 +76,8 @@ int main(int, char**)
testRuntimeSpan(std::span<std::string> (&s, 1));
testRuntimeSpan(std::span<std::string, 1>(&s, 1));
+ std::span<int, 0> sp;
+ testEmptySpan(sp);
+
return 0;
}
diff --git a/libcxx/test/std/containers/views/span.elem/front.pass.cpp b/libcxx/test/std/containers/views/span.elem/front.pass.cpp
index 7f18a2422b39..e17f7dd1576d 100644
--- a/libcxx/test/std/containers/views/span.elem/front.pass.cpp
+++ b/libcxx/test/std/containers/views/span.elem/front.pass.cpp
@@ -38,6 +38,12 @@ void testRuntimeSpan(Span sp)
assert(std::addressof(sp.front()) == sp.data());
}
+template <typename Span>
+void testEmptySpan(Span sp)
+{
+ if (!sp.empty())
+ [[maybe_unused]] auto res = sp.front();
+}
struct A{};
constexpr int iArr1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
@@ -71,5 +77,8 @@ int main(int, char**)
testRuntimeSpan(std::span<std::string> (&s, 1));
testRuntimeSpan(std::span<std::string, 1>(&s, 1));
+ std::span<int, 0> sp;
+ testEmptySpan(sp);
+
return 0;
}
More information about the libcxx-commits
mailing list