Bug 689066 - Fix c++11 incompatibility. r=luke.
authorRafael Ávila de Espíndola <respindola@mozilla.com>
Tue, 27 Sep 2011 10:01:34 -0400
changeset 77704 687e0bbfe996aad72f13fde04ac7f8ea733c16cc
parent 77703 d747526bd06644be1ec38fc21d8589b4121442e4
child 77705 9ba53832faf28544329de3bb0834cb8f25ef23af
push id2203
push userrespindola@mozilla.com
push dateTue, 27 Sep 2011 14:05:41 +0000
treeherdermozilla-inbound@687e0bbfe996 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs689066
milestone9.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 689066 - Fix c++11 incompatibility. r=luke. IF MoveRef is used in a rvalue position (which is expected), we could end up in a situation where, without this this, we would try to pass a T& to a move constructor, which fails. It is not clear if the compiler should instead use the copy constructor, but for now this lets us build with clang. See bug 689066 and llvm.org/pr11003 for the details.
js/src/jsutil.h
--- a/js/src/jsutil.h
+++ b/js/src/jsutil.h
@@ -45,16 +45,17 @@
 #define jsutil_h___
 
 #include "jstypes.h"
 #include "mozilla/Util.h"
 #include <stdlib.h>
 #include <string.h>
 
 #ifdef __cplusplus
+#include <utility>
 
 /* The public JS engine namespace. */
 namespace JS {}
 
 /* The mozilla-shared reusable template/utility namespace. */
 namespace mozilla {}
 
 /* The private JS engine namespace. */
@@ -828,17 +829,28 @@ enum MaybeReportError { REPORT_ERROR = t
  */
 template<typename T>
 class MoveRef {
   public:
     typedef T Referent;
     explicit MoveRef(T &t) : pointer(&t) { }
     T &operator*()  const { return *pointer; }
     T *operator->() const { return  pointer; }
-    operator T &()  const { return *pointer; }
+#ifdef __GXX_EXPERIMENTAL_CXX0X__
+    /* If MoveRef is used in a rvalue position (which is expected), we can
+       end up in a situation where, without this ifdef, we would try to pass
+       a T& to a move constructor, which fails. It is not clear if the compiler
+       should instead use the copy constructor, but for now this lets us build
+       with clang. See bug 689066 and llvm.org/pr11003 for the details. */
+    /* Note: We can probably remove MoveRef completely once we are comfortable
+       using c++11. */
+    operator T&& ()  const { return std::move(*pointer); }
+#else
+    operator T& ()   const { return *pointer; }
+#endif
   private:
     T *pointer;
 };
 
 template<typename T>
 MoveRef<T> Move(T &t) { return MoveRef<T>(t); }
 
 template<typename T>