Bug 689066 - Fix c++11 incompatibility. r=luke.
authorRafael Ávila de Espíndola <respindola@mozilla.com>
Thu, 29 Sep 2011 13:49:54 -0400
changeset 77865 9d8247091f4c27ffdade30ed81eee6dc6c3fb466
parent 77864 9928fb9a32b1ccc6aa2b61cbb19525a638010d73
child 77866 555c11e2c45984045298228e80c0fee400e068eb
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewersluke
bugs689066
milestone10.0a1
Bug 689066 - Fix c++11 incompatibility. r=luke.
js/src/jsutil.h
--- a/js/src/jsutil.h
+++ b/js/src/jsutil.h
@@ -830,17 +830,30 @@ 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 static_cast<T&&>(*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>