Bug 1448591 - Make MakeStringSpan(nullptr) return an empty span. r=froydnj.
authorHenri Sivonen <hsivonen@hsivonen.fi>
Sat, 24 Mar 2018 21:36:00 +0200
changeset 411557 1fb1569b61d292785497c3f662b8a387c638695a
parent 411556 e220521c6ff6ff9a45e19b3917ba95e678fd9932
child 411558 b4f0025c830369df929c2557390e5289affc13fc
push id101686
push useraciure@mozilla.com
push dateTue, 03 Apr 2018 21:59:31 +0000
treeherdermozilla-inbound@8d846598d35d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1448591
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1448591 - Make MakeStringSpan(nullptr) return an empty span. r=froydnj. MozReview-Commit-ID: EyuLeWjEL7w
mfbt/Span.h
mfbt/tests/gtest/TestSpan.cpp
--- a/mfbt/Span.h
+++ b/mfbt/Span.h
@@ -407,17 +407,18 @@ private:
  *
  * In addition to having constructors and MakeSpan() functions that take
  * various well-known types, a Span for an arbitrary type can be constructed
  * (via constructor or MakeSpan()) from a pointer and a length or a pointer
  * and another pointer pointing just past the last element.
  *
  * A Span<const char> or Span<const char16_t> can be obtained for const char*
  * or const char16_t pointing to a zero-terminated string using the
- * MakeStringSpan() function. Corresponding implicit constructor does not exist
+ * MakeStringSpan() function (which treats a nullptr argument equivalently
+ * to the empty string). Corresponding implicit constructor does not exist
  * in order to avoid accidental construction in cases where const char* or
  * const char16_t* do not point to a zero-terminated string.
  *
  * Span has methods that follow the Mozilla naming style and methods that
  * don't. The methods that follow the Mozilla naming style are meant to be
  * used directly from Mozilla code. The methods that don't are meant for
  * integration with C++11 range-based loops and with meta-programming that
  * expects the same methods that are found on the standard-library
@@ -1056,30 +1057,38 @@ MakeSpan(const Container& cont)
 template<class Ptr>
 Span<typename Ptr::element_type>
 MakeSpan(Ptr& aPtr, size_t aLength)
 {
   return Span<typename Ptr::element_type>(aPtr, aLength);
 }
 
 /**
- * Create span from C string.
+ * Create span from a zero-terminated C string. nullptr is
+ * treated as the empty string.
  */
 inline Span<const char>
 MakeStringSpan(const char* aZeroTerminated)
 {
+  if (!aZeroTerminated) {
+    return Span<const char>();
+  }
   return Span<const char>(aZeroTerminated, std::strlen(aZeroTerminated));
 }
 
 /**
- * Create span from UTF-16 C string.
+ * Create span from a zero-terminated UTF-16 C string. nullptr is
+ * treated as the empty string.
  */
 inline Span<const char16_t>
 MakeStringSpan(const char16_t* aZeroTerminated)
 {
+  if (!aZeroTerminated) {
+    return Span<const char16_t>();
+  }
   return Span<const char16_t>(aZeroTerminated, span_details::strlen16(aZeroTerminated));
 }
 
 } // namespace mozilla
 
 #ifdef _MSC_VER
 #if _MSC_VER < 1910
 #undef constexpr
--- a/mfbt/tests/gtest/TestSpan.cpp
+++ b/mfbt/tests/gtest/TestSpan.cpp
@@ -1190,16 +1190,21 @@ SPAN_TEST(from_xpcom_collections)
     ASSERT_EQ(s.data(), v.Elements());
     ASSERT_EQ(s[2], 3);
   }
 }
 
 SPAN_TEST(from_cstring)
 {
   {
+    const char* str = nullptr;
+    auto cs = MakeStringSpan(str);
+    ASSERT_EQ(cs.size(), 0U);
+  }
+  {
     const char* str = "abc";
 
     auto cs = MakeStringSpan(str);
     ASSERT_EQ(cs.size(), 3U);
     ASSERT_EQ(cs.data(), str);
     ASSERT_EQ(cs[2], 'c');
 
 #ifdef CONFIRM_COMPILATION_ERRORS
@@ -1229,16 +1234,21 @@ SPAN_TEST(from_cstring)
     Span<char> scca(arr); // error
     Span<const char> sccca(arr); // error
 
     Span<const char> scccea;
     scccea = arr; // error
 #endif
   }
   {
+    const char16_t* str = nullptr;
+    auto cs = MakeStringSpan(str);
+    ASSERT_EQ(cs.size(), 0U);
+  }
+  {
     char16_t arr[4] = {'a', 'b', 'c', 0};
     const char16_t* str = arr;
 
     auto cs = MakeStringSpan(str);
     ASSERT_EQ(cs.size(), 3U);
     ASSERT_EQ(cs.data(), str);
     ASSERT_EQ(cs[2], 'c');