Bug 1377351 - Part 5: Add a workaround for gcc 4.9 compiler bug, r=froydnj
authorNika Layzell <nika@thelayzells.com>
Thu, 05 Oct 2017 17:06:43 -0400
changeset 387004 6206e82fc670b2f73d1d8a746c6c555d756ad436
parent 387003 1aa544eccfc2546cdf5a321c912c5619468c587a
child 387005 6b9e12aef734b162c29885bbfb8cadf69f5db244
push id32705
push userryanvm@gmail.com
push dateThu, 19 Oct 2017 01:01:49 +0000
treeherdermozilla-central@a21099ce055f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1377351
milestone58.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 1377351 - Part 5: Add a workaround for gcc 4.9 compiler bug, r=froydnj MozReview-Commit-ID: CHywpZ4fvXf
xpcom/string/nsTLiteralString.h
xpcom/string/nsTString.h
xpcom/string/nsTStringRepr.h
xpcom/string/nsTSubstring.cpp
xpcom/string/nsTSubstring.h
--- a/xpcom/string/nsTLiteralString.h
+++ b/xpcom/string/nsTLiteralString.h
@@ -21,17 +21,26 @@
  * does not have a destructor.
  */
 template<typename T>
 class nsTLiteralString : public mozilla::detail::nsTStringRepr<T>
 {
 public:
 
   typedef nsTLiteralString<T> self_type;
+
+#ifdef __clang__
+  // bindgen w/ clang 3.9 at least chokes on a typedef, but using is okay.
+  using typename mozilla::detail::nsTStringRepr<T>::base_string_type;
+#else
+  // On the other hand msvc chokes on the using statement. It seems others
+  // don't care either way so we lump them in here.
   typedef typename mozilla::detail::nsTStringRepr<T>::base_string_type base_string_type;
+#endif
+
   typedef typename base_string_type::char_type char_type;
   typedef typename base_string_type::size_type size_type;
   typedef typename base_string_type::DataFlags DataFlags;
   typedef typename base_string_type::ClassFlags ClassFlags;
 
 public:
 
   /**
--- a/xpcom/string/nsTString.h
+++ b/xpcom/string/nsTString.h
@@ -33,16 +33,18 @@ public:
   // bindgen w/ clang 3.9 at least chokes on a typedef, but using is okay.
   using typename nsTSubstring<T>::substring_type;
 #else
   // On the other hand msvc chokes on the using statement. It seems others
   // don't care either way so we lump them in here.
   typedef typename nsTSubstring<T>::substring_type substring_type;
 #endif
 
+  typedef typename substring_type::literalstring_type literalstring_type;
+
   typedef typename substring_type::fallible_t fallible_t;
 
   typedef typename substring_type::char_type char_type;
   typedef typename substring_type::char_traits char_traits;
   typedef typename substring_type::incompatible_char_type incompatible_char_type;
 
   typedef typename substring_type::substring_tuple_type substring_tuple_type;
 
@@ -119,16 +121,24 @@ public:
 
   explicit
   nsTString(substring_type&& aReadable)
     : substring_type(ClassFlags::NULL_TERMINATED)
   {
     this->Assign(mozilla::Move(aReadable));
   }
 
+  // NOTE(nika): gcc 4.9 workaround. Remove when support is dropped.
+  explicit
+  nsTString(const literalstring_type& aReadable)
+    : substring_type(ClassFlags::NULL_TERMINATED)
+  {
+    this->Assign(aReadable);
+  }
+
 
   // |operator=| does not inherit, so we must define our own
   self_type& operator=(char_type aChar)
   {
     this->Assign(aChar);
     return *this;
   }
   self_type& operator=(const char_type* aData)
@@ -159,16 +169,22 @@ public:
     this->Assign(aStr);
     return *this;
   }
   self_type& operator=(substring_type&& aStr)
   {
     this->Assign(mozilla::Move(aStr));
     return *this;
   }
+  // NOTE(nika): gcc 4.9 workaround. Remove when support is dropped.
+  self_type& operator=(const literalstring_type& aStr)
+  {
+    this->Assign(aStr);
+    return *this;
+  }
   self_type& operator=(const substring_tuple_type& aTuple)
   {
     this->Assign(aTuple);
     return *this;
   }
 
   /**
    * returns the null-terminated string
@@ -569,16 +585,17 @@ public:
 
   typedef nsTString<T> base_string_type;
   typedef typename base_string_type::string_type string_type;
   typedef typename base_string_type::char_type char_type;
   typedef typename base_string_type::char_traits char_traits;
   typedef typename base_string_type::substring_type substring_type;
   typedef typename base_string_type::size_type size_type;
   typedef typename base_string_type::substring_tuple_type substring_tuple_type;
+  typedef typename base_string_type::literalstring_type literalstring_type;
 
   // These are only for internal use within the string classes:
   typedef typename base_string_type::DataFlags DataFlags;
   typedef typename base_string_type::ClassFlags ClassFlags;
 
   using typename base_string_type::IsChar;
   using typename base_string_type::IsChar16;
 
@@ -641,16 +658,24 @@ public:
 
   explicit
   nsTAutoStringN(substring_type&& aStr)
     : self_type()
   {
     this->Assign(mozilla::Move(aStr));
   }
 
+  // NOTE(nika): gcc 4.9 workaround. Remove when support is dropped.
+  explicit
+  nsTAutoStringN(const literalstring_type& aStr)
+    : self_type()
+  {
+    this->Assign(aStr);
+  }
+
   MOZ_IMPLICIT nsTAutoStringN(const substring_tuple_type& aTuple)
     : self_type()
   {
     this->Assign(aTuple);
   }
 
   // |operator=| does not inherit, so we must define our own
   self_type& operator=(char_type aChar)
@@ -686,16 +711,22 @@ public:
     this->Assign(aStr);
     return *this;
   }
   self_type& operator=(substring_type&& aStr)
   {
     this->Assign(mozilla::Move(aStr));
     return *this;
   }
+  // NOTE(nika): gcc 4.9 workaround. Remove when support is dropped.
+  self_type& operator=(const literalstring_type& aStr)
+  {
+    this->Assign(aStr);
+    return *this;
+  }
   self_type& operator=(const substring_tuple_type& aTuple)
   {
     this->Assign(aTuple);
     return *this;
   }
 
   static const size_t kStorageSize = N;
 
--- a/xpcom/string/nsTStringRepr.h
+++ b/xpcom/string/nsTStringRepr.h
@@ -8,16 +8,17 @@
 #define nsTStringRepr_h
 
 #include <type_traits> // std::enable_if
 
 #include "nsStringFlags.h"
 #include "nsCharTraits.h"
 
 template <typename T> class nsTSubstringTuple;
+template <typename T> class nsTLiteralString;
 
 // The base for string comparators
 template <typename T> class nsTStringComparator
 {
 public:
   typedef T char_type;
 
   nsTStringComparator() {}
@@ -69,16 +70,17 @@ public:
   typedef nsCharTraits<char_type> char_traits;
   typedef typename char_traits::incompatible_char_type incompatible_char_type;
 
   typedef nsTStringRepr<T> self_type;
   typedef self_type base_string_type;
 
   typedef nsTSubstring<T> substring_type;
   typedef nsTSubstringTuple<T> substring_tuple_type;
+  typedef nsTLiteralString<T> literalstring_type;
 
   typedef nsReadingIterator<char_type> const_iterator;
   typedef nsWritingIterator<char_type> iterator;
 
   typedef nsTStringComparator<char_type> comparator_type;
 
   typedef char_type* char_iterator;
   typedef const char_type* const_char_iterator;
--- a/xpcom/string/nsTSubstring.cpp
+++ b/xpcom/string/nsTSubstring.cpp
@@ -525,16 +525,24 @@ nsTSubstring<T>::Assign(self_type&& aStr
   // We don't truncate the source string if the allocation failed.
   if (!Assign(aStr, aFallible)) {
     return false;
   }
   aStr.Truncate();
   return true;
 }
 
+// NOTE(nika): gcc 4.9 workaround. Remove when support is dropped.
+template <typename T>
+void
+nsTSubstring<T>::Assign(const literalstring_type& aStr)
+{
+  Assign(aStr.AsString());
+}
+
 template <typename T>
 void
 nsTSubstring<T>::Assign(const substring_tuple_type& aTuple)
 {
   if (!Assign(aTuple, mozilla::fallible)) {
     AllocFailed(aTuple.Length());
   }
 }
--- a/xpcom/string/nsTSubstring.h
+++ b/xpcom/string/nsTSubstring.h
@@ -41,16 +41,17 @@ class nsTSubstring : public mozilla::det
 {
 public:
   typedef nsTSubstring<T> self_type;
 
   typedef nsTString<T> string_type;
 
   typedef typename mozilla::detail::nsTStringRepr<T> base_string_type;
   typedef typename base_string_type::substring_type substring_type;
+  typedef typename base_string_type::literalstring_type literalstring_type;
 
   typedef typename base_string_type::fallible_t fallible_t;
 
   typedef typename base_string_type::char_type char_type;
   typedef typename base_string_type::char_traits char_traits;
   typedef typename base_string_type::incompatible_char_type incompatible_char_type;
 
   typedef typename base_string_type::substring_tuple_type substring_tuple_type;
@@ -169,16 +170,23 @@ public:
                                        size_type aLength, const fallible_t&);
 
   void NS_FASTCALL Assign(const self_type&);
   MOZ_MUST_USE bool NS_FASTCALL Assign(const self_type&, const fallible_t&);
 
   void NS_FASTCALL Assign(self_type&&);
   MOZ_MUST_USE bool NS_FASTCALL Assign(self_type&&, const fallible_t&);
 
+  // XXX(nika): GCC 4.9 doesn't correctly resolve calls to Assign a
+  // nsLiteralCString into a nsTSubstring, due to a frontend bug. This explcit
+  // Assign overload (and the corresponding constructor and operator= overloads)
+  // are used to avoid this bug. Once we stop supporting GCC 4.9 we can remove
+  // them.
+  void NS_FASTCALL Assign(const literalstring_type&);
+
   void NS_FASTCALL Assign(const substring_tuple_type&);
   MOZ_MUST_USE bool NS_FASTCALL Assign(const substring_tuple_type&,
                                        const fallible_t&);
 
 #if defined(MOZ_USE_CHAR16_WRAPPER)
   template <typename EnableIfChar16 = IsChar16>
   void Assign(char16ptr_t aData)
   {
@@ -258,16 +266,22 @@ public:
     Assign(aStr);
     return *this;
   }
   self_type& operator=(self_type&& aStr)
   {
     Assign(mozilla::Move(aStr));
     return *this;
   }
+  // NOTE(nika): gcc 4.9 workaround. Remove when support is dropped.
+  self_type& operator=(const literalstring_type& aStr)
+  {
+    Assign(aStr);
+    return *this;
+  }
   self_type& operator=(const substring_tuple_type& aTuple)
   {
     Assign(aTuple);
     return *this;
   }
 
   // Adopt a heap-allocated char sequence for this string; is Voided if aData
   // is null. Useful for e.g. converting an strdup'd C string into an