Pull the new r369476 of base library from Chromium

The merge was done against r369476 which corresponds to git commit
0471d0e2e2ef4a544a63481a389e1df33ea7c00a of Jan 14, 2016

Change-Id: Ie6894cf65424cc5ad115110faccd51602b2d1234
Reviewed-on: https://weave-review.googlesource.com/2225
Reviewed-by: Alex Vakulenko <avakulenko@google.com>
diff --git a/third_party/chromium/base/memory/raw_scoped_refptr_mismatch_checker.h b/third_party/chromium/base/memory/raw_scoped_refptr_mismatch_checker.h
new file mode 100644
index 0000000..33bacba
--- /dev/null
+++ b/third_party/chromium/base/memory/raw_scoped_refptr_mismatch_checker.h
@@ -0,0 +1,64 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
+#define BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/template_util.h"
+#include "base/tuple.h"
+#include "build/build_config.h"
+
+// It is dangerous to post a task with a T* argument where T is a subtype of
+// RefCounted(Base|ThreadSafeBase), since by the time the parameter is used, the
+// object may already have been deleted since it was not held with a
+// scoped_refptr. Example: http://crbug.com/27191
+// The following set of traits are designed to generate a compile error
+// whenever this antipattern is attempted.
+
+namespace base {
+
+// This is a base internal implementation file used by task.h and callback.h.
+// Not for public consumption, so we wrap it in namespace internal.
+namespace internal {
+
+template <typename T>
+struct NeedsScopedRefptrButGetsRawPtr {
+#if defined(OS_WIN)
+  enum {
+    value = base::false_type::value
+  };
+#else
+  enum {
+    // Human readable translation: you needed to be a scoped_refptr if you are a
+    // raw pointer type and are convertible to a RefCounted(Base|ThreadSafeBase)
+    // type.
+    value = (std::is_pointer<T>::value &&
+             (std::is_convertible<T, subtle::RefCountedBase*>::value ||
+              std::is_convertible<T, subtle::RefCountedThreadSafeBase*>::value))
+  };
+#endif
+};
+
+template <typename Params>
+struct ParamsUseScopedRefptrCorrectly {
+  enum { value = 0 };
+};
+
+template <>
+struct ParamsUseScopedRefptrCorrectly<Tuple<>> {
+  enum { value = 1 };
+};
+
+template <typename Head, typename... Tail>
+struct ParamsUseScopedRefptrCorrectly<Tuple<Head, Tail...>> {
+  enum { value = !NeedsScopedRefptrButGetsRawPtr<Head>::value &&
+                 ParamsUseScopedRefptrCorrectly<Tuple<Tail...>>::value };
+};
+
+}  // namespace internal
+
+}  // namespace base
+
+#endif  // BASE_MEMORY_RAW_SCOPED_REFPTR_MISMATCH_CHECKER_H_
diff --git a/third_party/chromium/base/memory/ref_counted.h b/third_party/chromium/base/memory/ref_counted.h
index 52e8f00..95fa565 100644
--- a/third_party/chromium/base/memory/ref_counted.h
+++ b/third_party/chromium/base/memory/ref_counted.h
@@ -11,8 +11,8 @@
 
 #include "base/base_export.h"
 #include "base/compiler_specific.h"
+#include "base/macros.h"
 #include "base/logging.h"
-#include "base/move.h"
 #include "build/build_config.h"
 
 namespace base {
@@ -105,7 +105,7 @@
 //     ~MyFoo();
 //   };
 //
-// You should always make your destructor private, to avoid any code deleting
+// You should always make your destructor non-public, to avoid any code deleting
 // the object accidently while there are references to it.
 template <class T>
 class RefCounted : public subtle::RefCountedBase {
@@ -252,7 +252,6 @@
 //
 template <class T>
 class scoped_refptr {
-  TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_refptr)
  public:
   typedef T element_type;
 
@@ -264,17 +263,24 @@
       AddRef(ptr_);
   }
 
+  // Copy constructor.
   scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
     if (ptr_)
       AddRef(ptr_);
   }
 
+  // Copy conversion constructor.
   template <typename U>
   scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
     if (ptr_)
       AddRef(ptr_);
   }
 
+  // Move constructor. This is required in addition to the conversion
+  // constructor below in order for clang to warn about pessimizing moves.
+  scoped_refptr(scoped_refptr&& r) : ptr_(r.get()) { r.ptr_ = nullptr; }
+
+  // Move conversion constructor.
   template <typename U>
   scoped_refptr(scoped_refptr<U>&& r) : ptr_(r.get()) {
     r.ptr_ = nullptr;
@@ -318,13 +324,13 @@
   }
 
   scoped_refptr<T>& operator=(scoped_refptr<T>&& r) {
-    scoped_refptr<T>(r.Pass()).swap(*this);
+    scoped_refptr<T>(std::move(r)).swap(*this);
     return *this;
   }
 
   template <typename U>
   scoped_refptr<T>& operator=(scoped_refptr<U>&& r) {
-    scoped_refptr<T>(r.Pass()).swap(*this);
+    scoped_refptr<T>(std::move(r)).swap(*this);
     return *this;
   }
 
diff --git a/third_party/chromium/base/memory/ref_counted_unittest.cc b/third_party/chromium/base/memory/ref_counted_unittest.cc
index 9eda813..88ee981 100644
--- a/third_party/chromium/base/memory/ref_counted_unittest.cc
+++ b/third_party/chromium/base/memory/ref_counted_unittest.cc
@@ -169,26 +169,6 @@
   EXPECT_EQ(p2, p1);
 }
 
-TEST(RefCountedUnitTest, SelfMoveAssignment) {
-  ScopedRefPtrCountBase::reset_count();
-
-  {
-    ScopedRefPtrCountBase *raw = new ScopedRefPtrCountBase();
-    scoped_refptr<ScopedRefPtrCountBase> p(raw);
-    EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
-    EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
-
-    p = p.Pass();
-    EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
-    EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
-    EXPECT_EQ(raw, p.get());
-
-    // p goes out of scope.
-  }
-  EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
-  EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
-}
-
 TEST(RefCountedUnitTest, MoveAssignment1) {
   ScopedRefPtrCountBase::reset_count();
 
@@ -201,7 +181,7 @@
     {
       scoped_refptr<ScopedRefPtrCountBase> p2;
 
-      p2 = p1.Pass();
+      p2 = std::move(p1);
       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
       EXPECT_EQ(nullptr, p1.get());
@@ -232,7 +212,7 @@
       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
 
-      p1 = p2.Pass();
+      p1 = std::move(p2);
       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
       EXPECT_EQ(raw, p1.get());
@@ -263,7 +243,7 @@
       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
 
-      p1 = p2.Pass();
+      p1 = std::move(p2);
       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
       EXPECT_EQ(raw, p1.get());
@@ -294,7 +274,7 @@
       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
 
-      p2 = p1.Pass();
+      p2 = std::move(p1);
       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
       EXPECT_EQ(nullptr, p1.get());
@@ -326,7 +306,7 @@
       EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
 
-      p1 = p2.Pass();
+      p1 = std::move(p2);
       EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
       EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
       EXPECT_EQ(raw2, p1.get());
@@ -363,7 +343,7 @@
       EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
       EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
 
-      p1 = p2.Pass();
+      p1 = std::move(p2);
       EXPECT_EQ(2, ScopedRefPtrCountBase::constructor_count());
       EXPECT_EQ(1, ScopedRefPtrCountBase::destructor_count());
       EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
@@ -396,7 +376,7 @@
     EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
 
     {
-      scoped_refptr<ScopedRefPtrCountBase> p2(p1.Pass());
+      scoped_refptr<ScopedRefPtrCountBase> p2(std::move(p1));
       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
       EXPECT_EQ(nullptr, p1.get());
@@ -426,7 +406,7 @@
     EXPECT_EQ(0, ScopedRefPtrCountDerived::destructor_count());
 
     {
-      scoped_refptr<ScopedRefPtrCountBase> p2(p1.Pass());
+      scoped_refptr<ScopedRefPtrCountBase> p2(std::move(p1));
       EXPECT_EQ(1, ScopedRefPtrCountBase::constructor_count());
       EXPECT_EQ(0, ScopedRefPtrCountBase::destructor_count());
       EXPECT_EQ(1, ScopedRefPtrCountDerived::constructor_count());
diff --git a/third_party/chromium/base/memory/scoped_ptr.h b/third_party/chromium/base/memory/scoped_ptr.h
index 2aa1b32..d68604e 100644
--- a/third_party/chromium/base/memory/scoped_ptr.h
+++ b/third_party/chromium/base/memory/scoped_ptr.h
@@ -37,42 +37,43 @@
 // in that they are "movable but not copyable."  You can use the scopers in
 // the parameter and return types of functions to signify ownership transfer
 // in to and out of a function.  When calling a function that has a scoper
-// as the argument type, it must be called with the result of an analogous
-// scoper's Pass() function or another function that generates a temporary;
-// passing by copy will NOT work.  Here is an example using scoped_ptr:
+// as the argument type, it must be called with an rvalue of a scoper, which
+// can be created by using std::move(), or the result of another function that
+// generates a temporary; passing by copy will NOT work.  Here is an example
+// using scoped_ptr:
 //
 //   void TakesOwnership(scoped_ptr<Foo> arg) {
-//     // Do something with arg
+//     // Do something with arg.
 //   }
 //   scoped_ptr<Foo> CreateFoo() {
-//     // No need for calling Pass() because we are constructing a temporary
-//     // for the return value.
+//     // No need for calling std::move() for returning a move-only value, or
+//     // when you already have an rvalue as we do here.
 //     return scoped_ptr<Foo>(new Foo("new"));
 //   }
 //   scoped_ptr<Foo> PassThru(scoped_ptr<Foo> arg) {
-//     return arg.Pass();
+//     return arg;
 //   }
 //
 //   {
 //     scoped_ptr<Foo> ptr(new Foo("yay"));  // ptr manages Foo("yay").
-//     TakesOwnership(ptr.Pass());           // ptr no longer owns Foo("yay").
+//     TakesOwnership(std::move(ptr));       // ptr no longer owns Foo("yay").
 //     scoped_ptr<Foo> ptr2 = CreateFoo();   // ptr2 owns the return Foo.
 //     scoped_ptr<Foo> ptr3 =                // ptr3 now owns what was in ptr2.
-//         PassThru(ptr2.Pass());            // ptr2 is correspondingly nullptr.
+//         PassThru(std::move(ptr2));        // ptr2 is correspondingly nullptr.
 //   }
 //
-// Notice that if you do not call Pass() when returning from PassThru(), or
+// Notice that if you do not call std::move() when returning from PassThru(), or
 // when invoking TakesOwnership(), the code will not compile because scopers
 // are not copyable; they only implement move semantics which require calling
-// the Pass() function to signify a destructive transfer of state. CreateFoo()
-// is different though because we are constructing a temporary on the return
-// line and thus can avoid needing to call Pass().
+// the std::move() function to signify a destructive transfer of state.
+// CreateFoo() is different though because we are constructing a temporary on
+// the return line and thus can avoid needing to call std::move().
 //
-// Pass() properly handles upcast in initialization, i.e. you can use a
-// scoped_ptr<Child> to initialize a scoped_ptr<Parent>:
+// The conversion move-constructor properly handles upcast in initialization,
+// i.e. you can use a scoped_ptr<Child> to initialize a scoped_ptr<Parent>:
 //
 //   scoped_ptr<Foo> foo(new Foo());
-//   scoped_ptr<FooParent> parent(foo.Pass());
+//   scoped_ptr<FooParent> parent(std::move(foo));
 
 #ifndef BASE_MEMORY_SCOPED_PTR_H_
 #define BASE_MEMORY_SCOPED_PTR_H_
@@ -84,11 +85,13 @@
 #include <stddef.h>
 #include <stdlib.h>
 
-#include <algorithm>  // For std::swap().
 #include <iosfwd>
+#include <memory>
+#include <type_traits>
+#include <utility>
 
-#include "base/basictypes.h"
 #include "base/compiler_specific.h"
+#include "base/macros.h"
 #include "base/move.h"
 #include "base/template_util.h"
 
@@ -99,61 +102,6 @@
 class RefCountedThreadSafeBase;
 }  // namespace subtle
 
-// Function object which deletes its parameter, which must be a pointer.
-// If C is an array type, invokes 'delete[]' on the parameter; otherwise,
-// invokes 'delete'. The default deleter for scoped_ptr<T>.
-template <class T>
-struct DefaultDeleter {
-  DefaultDeleter() {}
-  template <typename U> DefaultDeleter(const DefaultDeleter<U>& other) {
-    // IMPLEMENTATION NOTE: C++11 20.7.1.1.2p2 only provides this constructor
-    // if U* is implicitly convertible to T* and U is not an array type.
-    //
-    // Correct implementation should use SFINAE to disable this
-    // constructor. However, since there are no other 1-argument constructors,
-    // using a COMPILE_ASSERT() based on is_convertible<> and requiring
-    // complete types is simpler and will cause compile failures for equivalent
-    // misuses.
-    //
-    // Note, the is_convertible<U*, T*> check also ensures that U is not an
-    // array. T is guaranteed to be a non-array, so any U* where U is an array
-    // cannot convert to T*.
-    enum { T_must_be_complete = sizeof(T) };
-    enum { U_must_be_complete = sizeof(U) };
-    COMPILE_ASSERT((std::is_convertible<U*, T*>::value),
-                   U_ptr_must_implicitly_convert_to_T_ptr);
-  }
-  inline void operator()(T* ptr) const {
-    enum { type_must_be_complete = sizeof(T) };
-    delete ptr;
-  }
-};
-
-// Specialization of DefaultDeleter for array types.
-template <class T>
-struct DefaultDeleter<T[]> {
-  inline void operator()(T* ptr) const {
-    enum { type_must_be_complete = sizeof(T) };
-    delete[] ptr;
-  }
-
- private:
-  // Disable this operator for any U != T because it is undefined to execute
-  // an array delete when the static type of the array mismatches the dynamic
-  // type.
-  //
-  // References:
-  //   C++98 [expr.delete]p3
-  //   http://cplusplus.github.com/LWG/lwg-defects.html#938
-  template <typename U> void operator()(U* array) const;
-};
-
-template <class T, int n>
-struct DefaultDeleter<T[n]> {
-  // Never allow someone to declare something like scoped_ptr<int[10]>.
-  COMPILE_ASSERT(sizeof(T) == -1, do_not_use_array_with_size_as_type);
-};
-
 // Function object which invokes 'free' on its parameter, which must be
 // a pointer. Can be used to store malloc-allocated pointers in scoped_ptr:
 //
@@ -175,17 +123,6 @@
   };
 };
 
-template <typename T>
-struct ShouldAbortOnSelfReset {
-  template <typename U>
-  static NoType Test(const typename U::AllowSelfReset*);
-
-  template <typename U>
-  static YesType Test(...);
-
-  static const bool value = sizeof(Test<T>(0)) == sizeof(YesType);
-};
-
 // Minimal implementation of the core logic of scoped_ptr, suitable for
 // reuse in both scoped_ptr and its specializations.
 template <class T, class D>
@@ -216,37 +153,28 @@
   }
 
   ~scoped_ptr_impl() {
-    if (data_.ptr != nullptr) {
-      // Not using get_deleter() saves one function call in non-optimized
-      // builds.
-      static_cast<D&>(data_)(data_.ptr);
-    }
+    // Match libc++, which calls reset() in its destructor.
+    // Use nullptr as the new value for three reasons:
+    // 1. libc++ does it.
+    // 2. Avoids infinitely recursing into destructors if two classes are owned
+    //    in a reference cycle (see ScopedPtrTest.ReferenceCycle).
+    // 3. If |this| is accessed in the future, in a use-after-free bug, attempts
+    //    to dereference |this|'s pointer should cause either a failure or a
+    //    segfault closer to the problem. If |this| wasn't reset to nullptr,
+    //    the access would cause the deleted memory to be read or written
+    //    leading to other more subtle issues.
+    reset(nullptr);
   }
 
   void reset(T* p) {
-    // This is a self-reset, which is no longer allowed for default deleters:
-    // https://crbug.com/162971
-    assert(!ShouldAbortOnSelfReset<D>::value || p == nullptr || p != data_.ptr);
-
-    // Note that running data_.ptr = p can lead to undefined behavior if
-    // get_deleter()(get()) deletes this. In order to prevent this, reset()
-    // should update the stored pointer before deleting its old value.
-    //
-    // However, changing reset() to use that behavior may cause current code to
-    // break in unexpected ways. If the destruction of the owned object
-    // dereferences the scoped_ptr when it is destroyed by a call to reset(),
-    // then it will incorrectly dispatch calls to |p| rather than the original
-    // value of |data_.ptr|.
-    //
-    // During the transition period, set the stored pointer to nullptr while
-    // deleting the object. Eventually, this safety check will be removed to
-    // prevent the scenario initially described from occuring and
-    // http://crbug.com/176091 can be closed.
+    // Match C++11's definition of unique_ptr::reset(), which requires changing
+    // the pointer before invoking the deleter on the old pointer. This prevents
+    // |this| from being accessed after the deleter is run, which may destroy
+    // |this|.
     T* old = data_.ptr;
-    data_.ptr = nullptr;
+    data_.ptr = p;
     if (old != nullptr)
       static_cast<D&>(data_)(old);
-    data_.ptr = p;
   }
 
   T* get() const { return data_.ptr; }
@@ -300,25 +228,27 @@
 // dereference it, you get the thread safety guarantees of T.
 //
 // The size of scoped_ptr is small. On most compilers, when using the
-// DefaultDeleter, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters will
-// increase the size proportional to whatever state they need to have. See
+// std::default_delete, sizeof(scoped_ptr<T>) == sizeof(T*). Custom deleters
+// will increase the size proportional to whatever state they need to have. See
 // comments inside scoped_ptr_impl<> for details.
 //
 // Current implementation targets having a strict subset of  C++11's
 // unique_ptr<> features. Known deficiencies include not supporting move-only
 // deleteres, function pointers as deleters, and deleters with reference
 // types.
-template <class T, class D = base::DefaultDeleter<T> >
+template <class T, class D = std::default_delete<T>>
 class scoped_ptr {
-  MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_ptr)
+  DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND(scoped_ptr)
 
-  COMPILE_ASSERT(base::internal::IsNotRefCounted<T>::value,
-                 T_is_refcounted_type_and_needs_scoped_refptr);
+  static_assert(!std::is_array<T>::value,
+                "scoped_ptr doesn't support array with size");
+  static_assert(base::internal::IsNotRefCounted<T>::value,
+                "T is a refcounted type and needs a scoped_refptr");
 
  public:
   // The element and deleter types.
-  typedef T element_type;
-  typedef D deleter_type;
+  using element_type = T;
+  using deleter_type = D;
 
   // Constructor.  Defaults to initializing with nullptr.
   scoped_ptr() : impl_(nullptr) {}
@@ -330,44 +260,87 @@
   scoped_ptr(element_type* p, const D& d) : impl_(p, d) {}
 
   // Constructor.  Allows construction from a nullptr.
-  scoped_ptr(decltype(nullptr)) : impl_(nullptr) {}
+  scoped_ptr(std::nullptr_t) : impl_(nullptr) {}
 
-  // Constructor.  Allows construction from a scoped_ptr rvalue for a
+  // Move constructor.
+  //
+  // IMPLEMENTATION NOTE: Clang requires a move constructor to be defined (and
+  // not just the conversion constructor) in order to warn on pessimizing moves.
+  // The requirements for the move constructor are specified in C++11
+  // 20.7.1.2.1.15-17, which has some subtleties around reference deleters. As
+  // we don't support reference (or move-only) deleters, the post conditions are
+  // trivially true: we always copy construct the deleter from other's deleter.
+  scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {}
+
+  // Conversion constructor.  Allows construction from a scoped_ptr rvalue for a
   // convertible type and deleter.
   //
-  // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this constructor distinct
-  // from the normal move constructor. By C++11 20.7.1.2.1.21, this constructor
-  // has different post-conditions if D is a reference type. Since this
-  // implementation does not support deleters with reference type,
-  // we do not need a separate move constructor allowing us to avoid one
-  // use of SFINAE. You only need to care about this if you modify the
-  // implementation of scoped_ptr.
-  template <typename U, typename V>
-  scoped_ptr(scoped_ptr<U, V>&& other)
-      : impl_(&other.impl_) {
-    COMPILE_ASSERT(!std::is_array<U>::value, U_cannot_be_an_array);
+  // IMPLEMENTATION NOTE: C++ 20.7.1.2.1.19 requires this constructor to only
+  // participate in overload resolution if all the following are true:
+  // - U is implicitly convertible to T: this is important for 2 reasons:
+  //     1. So type traits don't incorrectly return true, e.g.
+  //          std::is_convertible<scoped_ptr<Base>, scoped_ptr<Derived>>::value
+  //        should be false.
+  //     2. To make sure code like this compiles:
+  //        void F(scoped_ptr<int>);
+  //        void F(scoped_ptr<Base>);
+  //        // Ambiguous since both conversion constructors match.
+  //        F(scoped_ptr<Derived>());
+  // - U is not an array type: to prevent conversions from scoped_ptr<T[]> to
+  //   scoped_ptr<T>.
+  // - D is a reference type and E is the same type, or D is not a reference
+  //   type and E is implicitly convertible to D: again, we don't support
+  //   reference deleters, so we only worry about the latter requirement.
+  template <typename U,
+            typename E,
+            typename std::enable_if<!std::is_array<U>::value &&
+                                    std::is_convertible<U*, T*>::value &&
+                                    std::is_convertible<E, D>::value>::type* =
+                nullptr>
+  scoped_ptr(scoped_ptr<U, E>&& other)
+      : impl_(&other.impl_) {}
+
+  // operator=.
+  //
+  // IMPLEMENTATION NOTE: Unlike the move constructor, Clang does not appear to
+  // require a move assignment operator to trigger the pessimizing move warning:
+  // in this case, the warning triggers when moving a temporary. For consistency
+  // with the move constructor, we define it anyway. C++11 20.7.1.2.3.1-3
+  // defines several requirements around this: like the move constructor, the
+  // requirements are simplified by the fact that we don't support move-only or
+  // reference deleters.
+  scoped_ptr& operator=(scoped_ptr&& rhs) {
+    impl_.TakeState(&rhs.impl_);
+    return *this;
   }
 
   // operator=.  Allows assignment from a scoped_ptr rvalue for a convertible
   // type and deleter.
   //
   // IMPLEMENTATION NOTE: C++11 unique_ptr<> keeps this operator= distinct from
-  // the normal move assignment operator. By C++11 20.7.1.2.3.4, this templated
-  // form has different requirements on for move-only Deleters. Since this
-  // implementation does not support move-only Deleters, we do not need a
-  // separate move assignment operator allowing us to avoid one use of SFINAE.
-  // You only need to care about this if you modify the implementation of
-  // scoped_ptr.
-  template <typename U, typename V>
-  scoped_ptr& operator=(scoped_ptr<U, V>&& rhs) {
-    COMPILE_ASSERT(!std::is_array<U>::value, U_cannot_be_an_array);
+  // the normal move assignment operator. C++11 20.7.1.2.3.4-7 contains the
+  // requirement for this operator, but like the conversion constructor, the
+  // requirements are greatly simplified by not supporting move-only or
+  // reference deleters.
+  template <typename U,
+            typename E,
+            typename std::enable_if<!std::is_array<U>::value &&
+                                    std::is_convertible<U*, T*>::value &&
+                                    // Note that this really should be
+                                    // std::is_assignable, but <type_traits>
+                                    // appears to be missing this on some
+                                    // platforms. This is close enough (though
+                                    // it's not the same).
+                                    std::is_convertible<D, E>::value>::type* =
+                nullptr>
+  scoped_ptr& operator=(scoped_ptr<U, E>&& rhs) {
     impl_.TakeState(&rhs.impl_);
     return *this;
   }
 
   // operator=.  Allows assignment from a nullptr. Deletes the currently owned
   // object, if any.
-  scoped_ptr& operator=(decltype(nullptr)) {
+  scoped_ptr& operator=(std::nullptr_t) {
     reset();
     return *this;
   }
@@ -408,12 +381,6 @@
     return impl_.get() ? &scoped_ptr::impl_ : nullptr;
   }
 
-  // Comparison operators.
-  // These return whether two scoped_ptr refer to the same object, not just to
-  // two different but equal objects.
-  bool operator==(const element_type* p) const { return impl_.get() == p; }
-  bool operator!=(const element_type* p) const { return impl_.get() != p; }
-
   // Swap two scoped pointers.
   void swap(scoped_ptr& p2) {
     impl_.swap(p2.impl_);
@@ -434,23 +401,16 @@
 
   // Forbidden for API compatibility with std::unique_ptr.
   explicit scoped_ptr(int disallow_construction_from_null);
-
-  // Forbid comparison of scoped_ptr types.  If U != T, it totally
-  // doesn't make sense, and if U == T, it still doesn't make sense
-  // because you should never have the same object owned by two different
-  // scoped_ptrs.
-  template <class U> bool operator==(scoped_ptr<U> const& p2) const;
-  template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
 };
 
 template <class T, class D>
 class scoped_ptr<T[], D> {
-  MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_ptr)
+  DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND(scoped_ptr)
 
  public:
   // The element and deleter types.
-  typedef T element_type;
-  typedef D deleter_type;
+  using element_type = T;
+  using deleter_type = D;
 
   // Constructor.  Defaults to initializing with nullptr.
   scoped_ptr() : impl_(nullptr) {}
@@ -465,13 +425,11 @@
   //   (C++98 [expr.delete]p3). If you're doing this, fix your code.
   // - it cannot be const-qualified differently from T per unique_ptr spec
   //   (http://cplusplus.github.com/LWG/lwg-active.html#2118). Users wanting
-  //   to work around this may use implicit_cast<const T*>().
-  //   However, because of the first bullet in this comment, users MUST
-  //   NOT use implicit_cast<Base*>() to upcast the static type of the array.
+  //   to work around this may use const_cast<const T*>().
   explicit scoped_ptr(element_type* array) : impl_(array) {}
 
   // Constructor.  Allows construction from a nullptr.
-  scoped_ptr(decltype(nullptr)) : impl_(nullptr) {}
+  scoped_ptr(std::nullptr_t) : impl_(nullptr) {}
 
   // Constructor.  Allows construction from a scoped_ptr rvalue.
   scoped_ptr(scoped_ptr&& other) : impl_(&other.impl_) {}
@@ -484,7 +442,7 @@
 
   // operator=.  Allows assignment from a nullptr. Deletes the currently owned
   // array, if any.
-  scoped_ptr& operator=(decltype(nullptr)) {
+  scoped_ptr& operator=(std::nullptr_t) {
     reset();
     return *this;
   }
@@ -515,12 +473,6 @@
     return impl_.get() ? &scoped_ptr::impl_ : nullptr;
   }
 
-  // Comparison operators.
-  // These return whether two scoped_ptr refer to the same object, not just to
-  // two different but equal objects.
-  bool operator==(element_type* array) const { return impl_.get() == array; }
-  bool operator!=(element_type* array) const { return impl_.get() != array; }
-
   // Swap two scoped pointers.
   void swap(scoped_ptr& p2) {
     impl_.swap(p2.impl_);
@@ -553,13 +505,6 @@
   // reasons as the constructor above.
   template <typename U> void reset(U* array);
   void reset(int disallow_reset_from_null);
-
-  // Forbid comparison of scoped_ptr types.  If U != T, it totally
-  // doesn't make sense, and if U == T, it still doesn't make sense
-  // because you should never have the same object owned by two different
-  // scoped_ptrs.
-  template <class U> bool operator==(scoped_ptr<U> const& p2) const;
-  template <class U> bool operator!=(scoped_ptr<U> const& p2) const;
 };
 
 // Free functions
@@ -568,14 +513,84 @@
   p1.swap(p2);
 }
 
+template <class T1, class D1, class T2, class D2>
+bool operator==(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) {
+  return p1.get() == p2.get();
+}
 template <class T, class D>
-bool operator==(T* p1, const scoped_ptr<T, D>& p2) {
-  return p1 == p2.get();
+bool operator==(const scoped_ptr<T, D>& p, std::nullptr_t) {
+  return p.get() == nullptr;
+}
+template <class T, class D>
+bool operator==(std::nullptr_t, const scoped_ptr<T, D>& p) {
+  return p.get() == nullptr;
 }
 
+template <class T1, class D1, class T2, class D2>
+bool operator!=(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) {
+  return !(p1 == p2);
+}
 template <class T, class D>
-bool operator!=(T* p1, const scoped_ptr<T, D>& p2) {
-  return p1 != p2.get();
+bool operator!=(const scoped_ptr<T, D>& p, std::nullptr_t) {
+  return !(p == nullptr);
+}
+template <class T, class D>
+bool operator!=(std::nullptr_t, const scoped_ptr<T, D>& p) {
+  return !(p == nullptr);
+}
+
+template <class T1, class D1, class T2, class D2>
+bool operator<(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) {
+  return p1.get() < p2.get();
+}
+template <class T, class D>
+bool operator<(const scoped_ptr<T, D>& p, std::nullptr_t) {
+  auto* ptr = p.get();
+  return ptr < static_cast<decltype(ptr)>(nullptr);
+}
+template <class T, class D>
+bool operator<(std::nullptr_t, const scoped_ptr<T, D>& p) {
+  auto* ptr = p.get();
+  return static_cast<decltype(ptr)>(nullptr) < ptr;
+}
+
+template <class T1, class D1, class T2, class D2>
+bool operator>(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) {
+  return p2 < p1;
+}
+template <class T, class D>
+bool operator>(const scoped_ptr<T, D>& p, std::nullptr_t) {
+  return nullptr < p;
+}
+template <class T, class D>
+bool operator>(std::nullptr_t, const scoped_ptr<T, D>& p) {
+  return p < nullptr;
+}
+
+template <class T1, class D1, class T2, class D2>
+bool operator<=(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) {
+  return !(p1 > p2);
+}
+template <class T, class D>
+bool operator<=(const scoped_ptr<T, D>& p, std::nullptr_t) {
+  return !(p > nullptr);
+}
+template <class T, class D>
+bool operator<=(std::nullptr_t, const scoped_ptr<T, D>& p) {
+  return !(nullptr > p);
+}
+
+template <class T1, class D1, class T2, class D2>
+bool operator>=(const scoped_ptr<T1, D1>& p1, const scoped_ptr<T2, D2>& p2) {
+  return !(p1 < p2);
+}
+template <class T, class D>
+bool operator>=(const scoped_ptr<T, D>& p, std::nullptr_t) {
+  return !(p < nullptr);
+}
+template <class T, class D>
+bool operator>=(std::nullptr_t, const scoped_ptr<T, D>& p) {
+  return !(nullptr < p);
 }
 
 // A function to convert T* into scoped_ptr<T>
diff --git a/third_party/chromium/base/memory/scoped_ptr_unittest.cc b/third_party/chromium/base/memory/scoped_ptr_unittest.cc
index d4ff410..c1eb469 100644
--- a/third_party/chromium/base/memory/scoped_ptr_unittest.cc
+++ b/third_party/chromium/base/memory/scoped_ptr_unittest.cc
@@ -4,13 +4,16 @@
 
 #include "base/memory/scoped_ptr.h"
 
+#include <stddef.h>
+
 #include <sstream>
 
 #include <gtest/gtest.h>
 
-#include "base/basictypes.h"
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/macros.h"
+#include "build/build_config.h"
 
 namespace {
 
@@ -85,7 +88,7 @@
 int OverloadedNewAndDelete::g_delete_count = 0;
 
 scoped_ptr<ConDecLogger> PassThru(scoped_ptr<ConDecLogger> logger) {
-  return logger.Pass();
+  return logger;
 }
 
 void GrabAndDrop(scoped_ptr<ConDecLogger> logger) {
@@ -103,8 +106,8 @@
   int constructed = 0;
 
   // Ensure size of scoped_ptr<> doesn't increase unexpectedly.
-  COMPILE_ASSERT(sizeof(int*) >= sizeof(scoped_ptr<int>),
-                 scoped_ptr_larger_than_raw_ptr);
+  static_assert(sizeof(int*) >= sizeof(scoped_ptr<int>),
+                "scoped_ptr shouldn't be larger than the raw pointer");
 
   {
     scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
@@ -147,25 +150,25 @@
   }
   EXPECT_EQ(0, constructed);
 
-  // Test swap(), == and !=
+  // Test swap().
   {
     scoped_ptr<ConDecLogger> scoper1;
     scoped_ptr<ConDecLogger> scoper2;
-    EXPECT_TRUE(scoper1 == scoper2.get());
-    EXPECT_FALSE(scoper1 != scoper2.get());
+    EXPECT_TRUE(scoper1.get() == scoper2.get());
+    EXPECT_FALSE(scoper1.get() != scoper2.get());
 
     ConDecLogger* logger = new ConDecLogger(&constructed);
     scoper1.reset(logger);
     EXPECT_EQ(logger, scoper1.get());
     EXPECT_FALSE(scoper2.get());
-    EXPECT_FALSE(scoper1 == scoper2.get());
-    EXPECT_TRUE(scoper1 != scoper2.get());
+    EXPECT_FALSE(scoper1.get() == scoper2.get());
+    EXPECT_TRUE(scoper1.get() != scoper2.get());
 
     scoper2.swap(scoper1);
     EXPECT_EQ(logger, scoper2.get());
     EXPECT_FALSE(scoper1.get());
-    EXPECT_FALSE(scoper1 == scoper2.get());
-    EXPECT_TRUE(scoper1 != scoper2.get());
+    EXPECT_FALSE(scoper1.get() == scoper2.get());
+    EXPECT_TRUE(scoper1.get() != scoper2.get());
   }
   EXPECT_EQ(0, constructed);
 }
@@ -179,7 +182,7 @@
     EXPECT_EQ(1, constructed);
     EXPECT_TRUE(scoper.get());
 
-    scoped_ptr<ConDecLoggerParent> scoper_parent(scoper.Pass());
+    scoped_ptr<ConDecLoggerParent> scoper_parent(std::move(scoper));
     EXPECT_EQ(1, constructed);
     EXPECT_TRUE(scoper_parent.get());
     EXPECT_FALSE(scoper.get());
@@ -197,7 +200,7 @@
     EXPECT_TRUE(scoper.get());
 
     scoped_ptr<ConDecLoggerParent> scoper_parent;
-    scoper_parent = scoper.Pass();
+    scoper_parent = std::move(scoper);
     EXPECT_EQ(1, constructed);
     EXPECT_TRUE(scoper_parent.get());
     EXPECT_FALSE(scoper.get());
@@ -210,7 +213,7 @@
     EXPECT_EQ(1, constructed);
     EXPECT_TRUE(scoper.get());
 
-    scoped_ptr<const ConDecLogger> scoper_const(scoper.Pass());
+    scoped_ptr<const ConDecLogger> scoper_const(std::move(scoper));
     EXPECT_EQ(1, constructed);
     EXPECT_TRUE(scoper_const.get());
     EXPECT_FALSE(scoper.get());
@@ -228,7 +231,7 @@
     EXPECT_TRUE(scoper.get());
 
     scoped_ptr<const ConDecLogger> scoper_const;
-    scoper_const = scoper.Pass();
+    scoper_const = std::move(scoper);
     EXPECT_EQ(1, constructed);
     EXPECT_TRUE(scoper_const.get());
     EXPECT_FALSE(scoper.get());
@@ -252,7 +255,7 @@
     EXPECT_EQ(0, alternate_deletes);
 
     // Test this compiles and correctly overwrites the deleter state.
-    scoper = scoper_child.Pass();
+    scoper = std::move(scoper_child);
     EXPECT_TRUE(scoper);
     EXPECT_FALSE(scoper_child);
     EXPECT_EQ(1, deletes);
@@ -268,7 +271,8 @@
     EXPECT_TRUE(scoper_child);
     EXPECT_EQ(1, deletes);
     EXPECT_EQ(1, alternate_deletes);
-    scoped_ptr<double, CountingDeleter> scoper_construct(scoper_child.Pass());
+    scoped_ptr<double, CountingDeleter> scoper_construct(
+        std::move(scoper_child));
     EXPECT_TRUE(scoper_construct);
     EXPECT_FALSE(scoper_child);
     EXPECT_EQ(1, deletes);
@@ -328,12 +332,12 @@
   }
   EXPECT_EQ(0, constructed);
 
-  // Test swap(), ==, !=, and type-safe Boolean.
+  // Test swap() and type-safe Boolean.
   {
     scoped_ptr<ConDecLogger[]> scoper1;
     scoped_ptr<ConDecLogger[]> scoper2;
-    EXPECT_TRUE(scoper1 == scoper2.get());
-    EXPECT_FALSE(scoper1 != scoper2.get());
+    EXPECT_TRUE(scoper1.get() == scoper2.get());
+    EXPECT_FALSE(scoper1.get() != scoper2.get());
 
     ConDecLogger* loggers = new ConDecLogger[kNumLoggers];
     for (int i = 0; i < kNumLoggers; ++i) {
@@ -344,14 +348,14 @@
     EXPECT_EQ(loggers, scoper1.get());
     EXPECT_FALSE(scoper2);
     EXPECT_FALSE(scoper2.get());
-    EXPECT_FALSE(scoper1 == scoper2.get());
-    EXPECT_TRUE(scoper1 != scoper2.get());
+    EXPECT_FALSE(scoper1.get() == scoper2.get());
+    EXPECT_TRUE(scoper1.get() != scoper2.get());
 
     scoper2.swap(scoper1);
     EXPECT_EQ(loggers, scoper2.get());
     EXPECT_FALSE(scoper1.get());
-    EXPECT_FALSE(scoper1 == scoper2.get());
-    EXPECT_TRUE(scoper1 != scoper2.get());
+    EXPECT_FALSE(scoper1.get() == scoper2.get());
+    EXPECT_TRUE(scoper1.get() != scoper2.get());
   }
   EXPECT_EQ(0, constructed);
 
@@ -364,13 +368,13 @@
     }
     EXPECT_EQ(kNumLoggers, constructed);
 
-    // Test Pass() with constructor;
-    scoped_ptr<ConDecLogger[]> scoper2(scoper.Pass());
+    // Test moving with constructor;
+    scoped_ptr<ConDecLogger[]> scoper2(std::move(scoper));
     EXPECT_EQ(kNumLoggers, constructed);
 
-    // Test Pass() with assignment;
+    // Test moving with assignment;
     scoped_ptr<ConDecLogger[]> scoper3;
-    scoper3 = scoper2.Pass();
+    scoper3 = std::move(scoper2);
     EXPECT_EQ(kNumLoggers, constructed);
     EXPECT_FALSE(scoper);
     EXPECT_FALSE(scoper2);
@@ -379,27 +383,30 @@
   EXPECT_EQ(0, constructed);
 }
 
-TEST(ScopedPtrTest, PassBehavior) {
+TEST(ScopedPtrTest, MoveBehavior) {
   int constructed = 0;
   {
     ConDecLogger* logger = new ConDecLogger(&constructed);
     scoped_ptr<ConDecLogger> scoper(logger);
     EXPECT_EQ(1, constructed);
 
-    // Test Pass() with constructor;
-    scoped_ptr<ConDecLogger> scoper2(scoper.Pass());
+    // Test moving with constructor;
+    scoped_ptr<ConDecLogger> scoper2(std::move(scoper));
     EXPECT_EQ(1, constructed);
 
-    // Test Pass() with assignment;
+    // Test moving with assignment;
     scoped_ptr<ConDecLogger> scoper3;
-    scoper3 = scoper2.Pass();
+    scoper3 = std::move(scoper2);
     EXPECT_EQ(1, constructed);
     EXPECT_FALSE(scoper.get());
     EXPECT_FALSE(scoper2.get());
     EXPECT_TRUE(scoper3.get());
   }
 
-  // Test uncaught Pass() does not have side effects.
+#if !defined(OS_ANDROID) && !defined(OS_LINUX)
+  // Test uncaught Pass() does not have side effects, because Pass()
+  // is implemented by std::move().
+  // TODO(danakj): Remove this test case when we remove Pass().
   {
     ConDecLogger* logger = new ConDecLogger(&constructed);
     scoped_ptr<ConDecLogger> scoper(logger);
@@ -412,6 +419,7 @@
     EXPECT_TRUE(rvalue);
   }
   EXPECT_EQ(0, constructed);
+#endif
 
   // Test that passing to function which does nothing does not leak.
   {
@@ -420,7 +428,7 @@
     EXPECT_EQ(1, constructed);
 
     // Should auto-destruct logger by end of scope.
-    GrabAndDrop(scoper.Pass());
+    GrabAndDrop(std::move(scoper));
     EXPECT_FALSE(scoper.get());
   }
   EXPECT_EQ(0, constructed);
@@ -435,7 +443,7 @@
     scoped_ptr<ConDecLogger> scoper(logger);
     EXPECT_EQ(1, constructed);
 
-    PassThru(scoper.Pass());
+    PassThru(std::move(scoper));
     EXPECT_FALSE(scoper.get());
   }
   EXPECT_EQ(0, constructed);
@@ -447,7 +455,7 @@
     EXPECT_EQ(1, constructed);
 
     // Should auto-destruct logger by end of scope.
-    PassThru(scoper.Pass());
+    PassThru(std::move(scoper));
     EXPECT_FALSE(scoper.get());
   }
   EXPECT_EQ(0, constructed);
@@ -538,8 +546,8 @@
     // Pass the second deleter through a constructor and an operator=. Then
     // reinitialize the empty scopers to ensure that each one is deleting
     // properly.
-    scoped_ptr<double, CountingDeleter> scoper3(scoper2.Pass());
-    scoper = scoper3.Pass();
+    scoped_ptr<double, CountingDeleter> scoper3(std::move(scoper2));
+    scoper = std::move(scoper3);
     EXPECT_EQ(1, deletes);
 
     scoper2.reset(&dummy_value2);
@@ -550,33 +558,33 @@
   EXPECT_EQ(1, deletes);
   EXPECT_EQ(3, alternate_deletes);
 
-  // Test swap(), ==, !=, and type-safe Boolean.
+  // Test swap(), and type-safe Boolean.
   {
     scoped_ptr<double, CountingDeleter> scoper1(NULL,
                                                 CountingDeleter(&deletes));
     scoped_ptr<double, CountingDeleter> scoper2(NULL,
                                                 CountingDeleter(&deletes));
-    EXPECT_TRUE(scoper1 == scoper2.get());
-    EXPECT_FALSE(scoper1 != scoper2.get());
+    EXPECT_TRUE(scoper1.get() == scoper2.get());
+    EXPECT_FALSE(scoper1.get() != scoper2.get());
 
     scoper1.reset(&dummy_value);
     EXPECT_TRUE(scoper1);
     EXPECT_EQ(&dummy_value, scoper1.get());
     EXPECT_FALSE(scoper2);
     EXPECT_FALSE(scoper2.get());
-    EXPECT_FALSE(scoper1 == scoper2.get());
-    EXPECT_TRUE(scoper1 != scoper2.get());
+    EXPECT_FALSE(scoper1.get() == scoper2.get());
+    EXPECT_TRUE(scoper1.get() != scoper2.get());
 
     scoper2.swap(scoper1);
     EXPECT_EQ(&dummy_value, scoper2.get());
     EXPECT_FALSE(scoper1.get());
-    EXPECT_FALSE(scoper1 == scoper2.get());
-    EXPECT_TRUE(scoper1 != scoper2.get());
+    EXPECT_FALSE(scoper1.get() == scoper2.get());
+    EXPECT_TRUE(scoper1.get() != scoper2.get());
   }
 }
 
 // Sanity check test for overloaded new and delete operators. Does not do full
-// coverage of reset/release/Pass() operations as that is redundant with the
+// coverage of reset/release/move operations as that is redundant with the
 // above.
 TEST(ScopedPtrTest, OverloadedNewAndDelete) {
   {
@@ -584,7 +592,7 @@
     scoped_ptr<OverloadedNewAndDelete> scoper(new OverloadedNewAndDelete());
     EXPECT_TRUE(scoper.get());
 
-    scoped_ptr<OverloadedNewAndDelete> scoper2(scoper.Pass());
+    scoped_ptr<OverloadedNewAndDelete> scoper2(std::move(scoper));
   }
   EXPECT_EQ(1, OverloadedNewAndDelete::delete_count());
   EXPECT_EQ(1, OverloadedNewAndDelete::new_count());
@@ -633,55 +641,15 @@
   scoped_ptr<Sub> sub1(new Sub);
   scoped_ptr<Sub> sub2(new Sub);
 
-  // Upcast with Pass() works.
-  scoped_ptr<Super> super1 = sub1.Pass();
-  super1 = sub2.Pass();
+  // Upcast with move works.
+  scoped_ptr<Super> super1 = std::move(sub1);
+  super1 = std::move(sub2);
 
   // Upcast with an rvalue works.
   scoped_ptr<Super> super2 = SubClassReturn();
   super2 = SubClassReturn();
 }
 
-// Android death tests don't work properly with assert(). Yay.
-#if !defined(NDEBUG) && defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID)
-TEST(ScopedPtrTest, SelfResetAbortsWithDefaultDeleter) {
-  scoped_ptr<int> x(new int);
-  EXPECT_DEATH(x.reset(x.get()), "");
-}
-
-TEST(ScopedPtrTest, SelfResetAbortsWithDefaultArrayDeleter) {
-  scoped_ptr<int[]> y(new int[4]);
-  EXPECT_DEATH(y.reset(y.get()), "");
-}
-
-TEST(ScopedPtrTest, SelfResetAbortsWithDefaultFreeDeleter) {
-  scoped_ptr<int, base::FreeDeleter> z(static_cast<int*>(malloc(sizeof(int))));
-  EXPECT_DEATH(z.reset(z.get()), "");
-}
-
-// A custom deleter that doesn't opt out should still crash.
-TEST(ScopedPtrTest, SelfResetAbortsWithCustomDeleter) {
-  struct CustomDeleter {
-    inline void operator()(int* x) { delete x; }
-  };
-  scoped_ptr<int, CustomDeleter> x(new int);
-  EXPECT_DEATH(x.reset(x.get()), "");
-}
-#endif
-
-TEST(ScopedPtrTest, SelfResetWithCustomDeleterOptOut) {
-  // A custom deleter should be able to opt out of self-reset abort behavior.
-  struct NoOpDeleter {
-#if !defined(NDEBUG)
-    typedef void AllowSelfReset;
-#endif
-    inline void operator()(int*) {}
-  };
-  scoped_ptr<int> owner(new int);
-  scoped_ptr<int, NoOpDeleter> x(owner.get());
-  x.reset(x.get());
-}
-
 // Logging a scoped_ptr<T> to an ostream shouldn't convert it to a boolean
 // value first.
 TEST(ScopedPtrTest, LoggingDoesntConvertToBoolean) {
@@ -694,3 +662,182 @@
 
   EXPECT_EQ(s2.str(), s1.str());
 }
+
+TEST(ScopedPtrTest, ReferenceCycle) {
+  struct StructB;
+  struct StructA {
+    scoped_ptr<StructB> b;
+  };
+
+  struct StructB {
+    scoped_ptr<StructA> a;
+  };
+
+  // Create a reference cycle.
+  StructA* a = new StructA;
+  a->b.reset(new StructB);
+  a->b->a.reset(a);
+
+  // Break the cycle by calling reset(). This will cause |a| (and hence, |a->b|)
+  // to be deleted before the call to reset() returns. This tests that the
+  // implementation of scoped_ptr::reset() doesn't access |this| after it
+  // deletes the underlying pointer. This behaviour is consistent with the
+  // definition of unique_ptr::reset in C++11.
+  a->b.reset();
+
+  // Go again, but this time, break the cycle by invoking |a|'s destructor. This
+  // tests that the implementation of ~scoped_ptr doesn't infinitely recurse
+  // into the destructors of |a| and |a->b|. Note, deleting |a| instead will
+  // cause |a| to be double-free'd because |a->b| owns |a| and deletes it via
+  // its destructor.
+  a = new StructA;
+  a->b.reset(new StructB);
+  a->b->a.reset(a);
+  a->~StructA();
+}
+
+TEST(ScopedPtrTest, Operators) {
+  struct Parent {};
+  struct Child : public Parent {};
+
+  scoped_ptr<Parent> p(new Parent);
+  scoped_ptr<Parent> p2(new Parent);
+  scoped_ptr<Child> c(new Child);
+  scoped_ptr<Parent> pnull;
+
+  // Operator==.
+  EXPECT_TRUE(p == p);
+  EXPECT_FALSE(p == c);
+  EXPECT_FALSE(p == p2);
+  EXPECT_FALSE(p == pnull);
+
+  EXPECT_FALSE(p == nullptr);
+  EXPECT_FALSE(nullptr == p);
+  EXPECT_TRUE(pnull == nullptr);
+  EXPECT_TRUE(nullptr == pnull);
+
+  // Operator!=.
+  EXPECT_FALSE(p != p);
+  EXPECT_TRUE(p != c);
+  EXPECT_TRUE(p != p2);
+  EXPECT_TRUE(p != pnull);
+
+  EXPECT_TRUE(p != nullptr);
+  EXPECT_TRUE(nullptr != p);
+  EXPECT_FALSE(pnull != nullptr);
+  EXPECT_FALSE(nullptr != pnull);
+
+  // Compare two scoped_ptr<T>.
+  EXPECT_EQ(p.get() < p2.get(), p < p2);
+  EXPECT_EQ(p.get() <= p2.get(), p <= p2);
+  EXPECT_EQ(p.get() > p2.get(), p > p2);
+  EXPECT_EQ(p.get() >= p2.get(), p >= p2);
+  EXPECT_EQ(p2.get() < p.get(), p2 < p);
+  EXPECT_EQ(p2.get() <= p.get(), p2 <= p);
+  EXPECT_EQ(p2.get() > p.get(), p2 > p);
+  EXPECT_EQ(p2.get() >= p.get(), p2 >= p);
+
+  // And convertible scoped_ptr<T> and scoped_ptr<U>.
+  EXPECT_EQ(p.get() < c.get(), p < c);
+  EXPECT_EQ(p.get() <= c.get(), p <= c);
+  EXPECT_EQ(p.get() > c.get(), p > c);
+  EXPECT_EQ(p.get() >= c.get(), p >= c);
+  EXPECT_EQ(c.get() < p.get(), c < p);
+  EXPECT_EQ(c.get() <= p.get(), c <= p);
+  EXPECT_EQ(c.get() > p.get(), c > p);
+  EXPECT_EQ(c.get() >= p.get(), c >= p);
+
+  // Compare to nullptr.
+  EXPECT_TRUE(p > nullptr);
+  EXPECT_FALSE(nullptr > p);
+  EXPECT_FALSE(pnull > nullptr);
+  EXPECT_FALSE(nullptr > pnull);
+
+  EXPECT_TRUE(p >= nullptr);
+  EXPECT_FALSE(nullptr >= p);
+  EXPECT_TRUE(pnull >= nullptr);
+  EXPECT_TRUE(nullptr >= pnull);
+
+  EXPECT_FALSE(p < nullptr);
+  EXPECT_TRUE(nullptr < p);
+  EXPECT_FALSE(pnull < nullptr);
+  EXPECT_FALSE(nullptr < pnull);
+
+  EXPECT_FALSE(p <= nullptr);
+  EXPECT_TRUE(nullptr <= p);
+  EXPECT_TRUE(pnull <= nullptr);
+  EXPECT_TRUE(nullptr <= pnull);
+};
+
+TEST(ScopedPtrTest, ArrayOperators) {
+  struct Parent {};
+  struct Child : public Parent {};
+
+  scoped_ptr<Parent[]> p(new Parent[1]);
+  scoped_ptr<Parent[]> p2(new Parent[1]);
+  scoped_ptr<Child[]> c(new Child[1]);
+  scoped_ptr<Parent[]> pnull;
+
+  // Operator==.
+  EXPECT_TRUE(p == p);
+  EXPECT_FALSE(p == c);
+  EXPECT_FALSE(p == p2);
+  EXPECT_FALSE(p == pnull);
+
+  EXPECT_FALSE(p == nullptr);
+  EXPECT_FALSE(nullptr == p);
+  EXPECT_TRUE(pnull == nullptr);
+  EXPECT_TRUE(nullptr == pnull);
+
+  // Operator!=.
+  EXPECT_FALSE(p != p);
+  EXPECT_TRUE(p != c);
+  EXPECT_TRUE(p != p2);
+  EXPECT_TRUE(p != pnull);
+
+  EXPECT_TRUE(p != nullptr);
+  EXPECT_TRUE(nullptr != p);
+  EXPECT_FALSE(pnull != nullptr);
+  EXPECT_FALSE(nullptr != pnull);
+
+  // Compare two scoped_ptr<T>.
+  EXPECT_EQ(p.get() < p2.get(), p < p2);
+  EXPECT_EQ(p.get() <= p2.get(), p <= p2);
+  EXPECT_EQ(p.get() > p2.get(), p > p2);
+  EXPECT_EQ(p.get() >= p2.get(), p >= p2);
+  EXPECT_EQ(p2.get() < p.get(), p2 < p);
+  EXPECT_EQ(p2.get() <= p.get(), p2 <= p);
+  EXPECT_EQ(p2.get() > p.get(), p2 > p);
+  EXPECT_EQ(p2.get() >= p.get(), p2 >= p);
+
+  // And convertible scoped_ptr<T> and scoped_ptr<U>.
+  EXPECT_EQ(p.get() < c.get(), p < c);
+  EXPECT_EQ(p.get() <= c.get(), p <= c);
+  EXPECT_EQ(p.get() > c.get(), p > c);
+  EXPECT_EQ(p.get() >= c.get(), p >= c);
+  EXPECT_EQ(c.get() < p.get(), c < p);
+  EXPECT_EQ(c.get() <= p.get(), c <= p);
+  EXPECT_EQ(c.get() > p.get(), c > p);
+  EXPECT_EQ(c.get() >= p.get(), c >= p);
+
+  // Compare to nullptr.
+  EXPECT_TRUE(p > nullptr);
+  EXPECT_FALSE(nullptr > p);
+  EXPECT_FALSE(pnull > nullptr);
+  EXPECT_FALSE(nullptr > pnull);
+
+  EXPECT_TRUE(p >= nullptr);
+  EXPECT_FALSE(nullptr >= p);
+  EXPECT_TRUE(pnull >= nullptr);
+  EXPECT_TRUE(nullptr >= pnull);
+
+  EXPECT_FALSE(p < nullptr);
+  EXPECT_TRUE(nullptr < p);
+  EXPECT_FALSE(pnull < nullptr);
+  EXPECT_FALSE(nullptr < pnull);
+
+  EXPECT_FALSE(p <= nullptr);
+  EXPECT_TRUE(nullptr <= p);
+  EXPECT_TRUE(pnull <= nullptr);
+  EXPECT_TRUE(nullptr <= pnull);
+}
diff --git a/third_party/chromium/base/memory/weak_ptr.h b/third_party/chromium/base/memory/weak_ptr.h
index e07beeb..c1c52ee 100644
--- a/third_party/chromium/base/memory/weak_ptr.h
+++ b/third_party/chromium/base/memory/weak_ptr.h
@@ -16,6 +16,7 @@
 //
 //  class Controller {
 //   public:
+//    Controller() : weak_factory_(this) {}
 //    void SpawnWorker() { Worker::StartNew(weak_factory_.GetWeakPtr()); }
 //    void WorkComplete(const Result& result) { ... }
 //   private:
@@ -58,15 +59,20 @@
 // off to other task runners, e.g. to use to post tasks back to object on the
 // bound sequence.
 //
-// Invalidating the factory's WeakPtrs un-binds it from the sequence, allowing
-// it to be passed for a different sequence to use or delete it.
+// If all WeakPtr objects are destroyed or invalidated then the factory is
+// unbound from the SequencedTaskRunner/Thread. The WeakPtrFactory may then be
+// destroyed, or new WeakPtr objects may be used, from a different sequence.
+//
+// Thus, at least one WeakPtr object must exist and have been dereferenced on
+// the correct thread to enforce that other WeakPtr objects will enforce they
+// are used on the desired thread.
 
 #ifndef BASE_MEMORY_WEAK_PTR_H_
 #define BASE_MEMORY_WEAK_PTR_H_
 
-#include "base/basictypes.h"
 #include "base/base_export.h"
 #include "base/logging.h"
+#include "base/macros.h"
 #include "base/memory/ref_counted.h"
 
 namespace base {
@@ -152,8 +158,8 @@
   static WeakPtr<Derived> StaticAsWeakPtr(Derived* t) {
     typedef std::is_convertible<Derived*, internal::SupportsWeakPtrBase*>
         convertible;
-    COMPILE_ASSERT(convertible::value,
-                   AsWeakPtr_argument_inherits_from_SupportsWeakPtr);
+    static_assert(convertible::value,
+                  "AsWeakPtr argument must inherit from SupportsWeakPtr");
     return AsWeakPtrImpl<Derived>(t, *t);
   }