1 /* Unit tests for unique-ptr.h. 2 Copyright (C) 2017-2018 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free 8 Software Foundation; either version 3, or (at your option) any later 9 version. 10 11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GCC; see the file COPYING3. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20 #include "config.h" 21 #define INCLUDE_UNIQUE_PTR 22 #include "system.h" 23 #include "coretypes.h" 24 #include "selftest.h" 25 26 #if CHECKING_P 27 28 namespace selftest { 29 30 namespace { 31 32 /* A class for counting ctor and dtor invocations. */ 33 34 struct stats 35 { 36 stats () : ctor_count (0), dtor_count (0) {} 37 38 int ctor_count; 39 int dtor_count; 40 }; 41 42 /* A class that uses "stats" to track its ctor and dtor invocations. */ 43 44 class foo 45 { 46 public: 47 foo (stats &s) : m_s (s) { ++m_s.ctor_count; } 48 ~foo () { ++m_s.dtor_count; } 49 50 int example_method () const { return 42; } 51 52 private: 53 foo (const foo&); 54 foo & operator= (const foo &); 55 56 private: 57 stats &m_s; 58 }; 59 60 /* A struct for testing unique_ptr<T[]>. */ 61 62 struct has_default_ctor 63 { 64 has_default_ctor () : m_field (42) {} 65 int m_field; 66 }; 67 68 /* A dummy struct for testing unique_xmalloc_ptr. */ 69 70 struct dummy 71 { 72 int field; 73 }; 74 75 } // anonymous namespace 76 77 /* Verify that the default ctor inits ptrs to NULL. */ 78 79 static void 80 test_null_ptr () 81 { 82 gnu::unique_ptr<void *> p; 83 ASSERT_EQ (NULL, p); 84 85 gnu::unique_xmalloc_ptr<void *> q; 86 ASSERT_EQ (NULL, q); 87 } 88 89 /* Verify that deletion happens when a unique_ptr goes out of scope. */ 90 91 static void 92 test_implicit_deletion () 93 { 94 stats s; 95 ASSERT_EQ (0, s.ctor_count); 96 ASSERT_EQ (0, s.dtor_count); 97 98 { 99 gnu::unique_ptr<foo> f (new foo (s)); 100 ASSERT_NE (NULL, f); 101 ASSERT_EQ (1, s.ctor_count); 102 ASSERT_EQ (0, s.dtor_count); 103 } 104 105 /* Verify that the foo was implicitly deleted. */ 106 ASSERT_EQ (1, s.ctor_count); 107 ASSERT_EQ (1, s.dtor_count); 108 } 109 110 /* Verify that we can assign to a NULL unique_ptr. */ 111 112 static void 113 test_overwrite_of_null () 114 { 115 stats s; 116 ASSERT_EQ (0, s.ctor_count); 117 ASSERT_EQ (0, s.dtor_count); 118 119 { 120 gnu::unique_ptr<foo> f; 121 ASSERT_EQ (NULL, f); 122 ASSERT_EQ (0, s.ctor_count); 123 ASSERT_EQ (0, s.dtor_count); 124 125 /* Overwrite with a non-NULL value. */ 126 f = gnu::unique_ptr<foo> (new foo (s)); 127 ASSERT_EQ (1, s.ctor_count); 128 ASSERT_EQ (0, s.dtor_count); 129 } 130 131 /* Verify that the foo is implicitly deleted. */ 132 ASSERT_EQ (1, s.ctor_count); 133 ASSERT_EQ (1, s.dtor_count); 134 } 135 136 /* Verify that we can assign to a non-NULL unique_ptr. */ 137 138 static void 139 test_overwrite_of_non_null () 140 { 141 stats s; 142 ASSERT_EQ (0, s.ctor_count); 143 ASSERT_EQ (0, s.dtor_count); 144 145 { 146 gnu::unique_ptr<foo> f (new foo (s)); 147 ASSERT_NE (NULL, f); 148 ASSERT_EQ (1, s.ctor_count); 149 ASSERT_EQ (0, s.dtor_count); 150 151 /* Overwrite with a different value. */ 152 f = gnu::unique_ptr<foo> (new foo (s)); 153 ASSERT_EQ (2, s.ctor_count); 154 ASSERT_EQ (1, s.dtor_count); 155 } 156 157 /* Verify that the 2nd foo was implicitly deleted. */ 158 ASSERT_EQ (2, s.ctor_count); 159 ASSERT_EQ (2, s.dtor_count); 160 } 161 162 /* Verify that unique_ptr's overloaded ops work. */ 163 164 static void 165 test_overloaded_ops () 166 { 167 stats s; 168 gnu::unique_ptr<foo> f (new foo (s)); 169 ASSERT_EQ (42, f->example_method ()); 170 ASSERT_EQ (42, (*f).example_method ()); 171 ASSERT_EQ (f, f); 172 ASSERT_NE (NULL, f.get ()); 173 174 gnu::unique_ptr<foo> g (new foo (s)); 175 ASSERT_NE (f, g); 176 } 177 178 /* Verify that the gnu::unique_ptr specialization for T[] works. */ 179 180 static void 181 test_array_new () 182 { 183 const int num = 10; 184 gnu::unique_ptr<has_default_ctor[]> p (new has_default_ctor[num]); 185 ASSERT_NE (NULL, p.get ()); 186 /* Verify that operator[] works, and that the default ctor was called 187 on each element. */ 188 for (int i = 0; i < num; i++) 189 ASSERT_EQ (42, p[i].m_field); 190 } 191 192 /* Verify that gnu::unique_xmalloc_ptr works. */ 193 194 static void 195 test_xmalloc () 196 { 197 gnu::unique_xmalloc_ptr<dummy> p (XNEW (dummy)); 198 ASSERT_NE (NULL, p.get ()); 199 } 200 201 /* Verify the gnu::unique_xmalloc_ptr specialization for T[]. */ 202 203 static void 204 test_xmalloc_array () 205 { 206 const int num = 10; 207 gnu::unique_xmalloc_ptr<dummy[]> p (XNEWVEC (dummy, num)); 208 ASSERT_NE (NULL, p.get ()); 209 210 /* Verify that operator[] works. */ 211 for (int i = 0; i < num; i++) 212 p[i].field = 42; 213 for (int i = 0; i < num; i++) 214 ASSERT_EQ (42, p[i].field); 215 } 216 217 /* Run all of the selftests within this file. */ 218 219 void 220 unique_ptr_tests_cc_tests () 221 { 222 test_null_ptr (); 223 test_implicit_deletion (); 224 test_overwrite_of_null (); 225 test_overwrite_of_non_null (); 226 test_overloaded_ops (); 227 test_array_new (); 228 test_xmalloc (); 229 test_xmalloc_array (); 230 } 231 232 } // namespace selftest 233 234 #endif /* #if CHECKING_P */ 235