Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / base / memory / scoped_ptr_unittest.cc
index e0c1548..3f169a7 100644 (file)
@@ -25,11 +25,14 @@ class ConDecLogger : public ConDecLoggerParent {
  public:
   ConDecLogger() : ptr_(NULL) { }
   explicit ConDecLogger(int* ptr) { SetPtr(ptr); }
-  virtual ~ConDecLogger() { --*ptr_; }
+  ~ConDecLogger() override { --*ptr_; }
 
-  virtual void SetPtr(int* ptr) OVERRIDE { ptr_ = ptr; ++*ptr_; }
+  void SetPtr(int* ptr) override {
+    ptr_ = ptr;
+    ++*ptr_;
+  }
 
-  virtual int SomeMeth(int x) const OVERRIDE { return x; }
+  int SomeMeth(int x) const override { return x; }
 
  private:
   int* ptr_;
@@ -91,11 +94,6 @@ scoped_ptr<ConDecLogger> TestReturnOfType(int* constructed) {
   return scoped_ptr<ConDecLogger>(new ConDecLogger(constructed));
 }
 
-scoped_ptr<ConDecLoggerParent> UpcastUsingPassAs(
-    scoped_ptr<ConDecLogger> object) {
-  return object.PassAs<ConDecLoggerParent>();
-}
-
 }  // namespace
 
 TEST(ScopedPtrTest, ScopedPtr) {
@@ -398,15 +396,17 @@ TEST(ScopedPtrTest, PassBehavior) {
     EXPECT_TRUE(scoper3.get());
   }
 
-  // Test uncaught Pass() does not leak.
+  // Test uncaught Pass() does not have side effects.
   {
     ConDecLogger* logger = new ConDecLogger(&constructed);
     scoped_ptr<ConDecLogger> scoper(logger);
     EXPECT_EQ(1, constructed);
 
     // Should auto-destruct logger by end of scope.
-    scoper.Pass();
-    EXPECT_FALSE(scoper.get());
+    scoped_ptr<ConDecLogger>&& rvalue = scoper.Pass();
+    // The Pass() function mimics std::move(), which does not have side-effects.
+    EXPECT_TRUE(scoper.get());
+    EXPECT_TRUE(rvalue);
   }
   EXPECT_EQ(0, constructed);
 
@@ -457,22 +457,6 @@ TEST(ScopedPtrTest, ReturnTypeBehavior) {
   EXPECT_EQ(0, constructed);
 }
 
-TEST(ScopedPtrTest, PassAs) {
-  int constructed = 0;
-  {
-    scoped_ptr<ConDecLogger> scoper(new ConDecLogger(&constructed));
-    EXPECT_EQ(1, constructed);
-    EXPECT_TRUE(scoper.get());
-
-    scoped_ptr<ConDecLoggerParent> scoper_parent;
-    scoper_parent = UpcastUsingPassAs(scoper.Pass());
-    EXPECT_EQ(1, constructed);
-    EXPECT_TRUE(scoper_parent.get());
-    EXPECT_FALSE(scoper.get());
-  }
-  EXPECT_EQ(0, constructed);
-}
-
 TEST(ScopedPtrTest, CustomDeleter) {
   double dummy_value;  // Custom deleter never touches this value.
   int deletes = 0;
@@ -602,3 +586,93 @@ TEST(ScopedPtrTest, OverloadedNewAndDelete) {
   EXPECT_EQ(1, OverloadedNewAndDelete::delete_count());
   EXPECT_EQ(1, OverloadedNewAndDelete::new_count());
 }
+
+scoped_ptr<int> NullIntReturn() {
+  return nullptr;
+}
+
+TEST(ScopedPtrTest, Nullptr) {
+  scoped_ptr<int> scoper1(nullptr);
+  scoped_ptr<int> scoper2(new int);
+  scoper2 = nullptr;
+  scoped_ptr<int> scoper3(NullIntReturn());
+  scoped_ptr<int> scoper4 = NullIntReturn();
+  EXPECT_EQ(nullptr, scoper1.get());
+  EXPECT_EQ(nullptr, scoper2.get());
+  EXPECT_EQ(nullptr, scoper3.get());
+  EXPECT_EQ(nullptr, scoper4.get());
+}
+
+scoped_ptr<int[]> NullIntArrayReturn() {
+  return nullptr;
+}
+
+TEST(ScopedPtrTest, NullptrArray) {
+  scoped_ptr<int[]> scoper1(nullptr);
+  scoped_ptr<int[]> scoper2(new int[3]);
+  scoper2 = nullptr;
+  scoped_ptr<int[]> scoper3(NullIntArrayReturn());
+  scoped_ptr<int[]> scoper4 = NullIntArrayReturn();
+  EXPECT_EQ(nullptr, scoper1.get());
+  EXPECT_EQ(nullptr, scoper2.get());
+  EXPECT_EQ(nullptr, scoper3.get());
+  EXPECT_EQ(nullptr, scoper4.get());
+}
+
+class Super {};
+class Sub : public Super {};
+
+scoped_ptr<Sub> SubClassReturn() {
+  return make_scoped_ptr(new Sub);
+}
+
+TEST(ScopedPtrTest, Conversion) {
+  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 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 {
+    typedef void AllowSelfReset;
+    inline void operator()(int*) {}
+  };
+  scoped_ptr<int> owner(new int);
+  scoped_ptr<int, NoOpDeleter> x(owner.get());
+  x.reset(x.get());
+}