1/* Unit tests for unique-ptr.h.
2 Copyright (C) 2017 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along 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
28namespace selftest {
29
30namespace {
31
32/* A class for counting ctor and dtor invocations. */
33
34struct 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
44class foo
45{
46public:
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
52private:
53 foo (const foo&);
54 foo & operator= (const foo &);
55
56private:
57 stats &m_s;
58};
59
60/* A struct for testing unique_ptr<T[]>. */
61
62struct 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
70struct dummy
71{
72 int field;
73};
74
75} // anonymous namespace
76
77/* Verify that the default ctor inits ptrs to NULL. */
78
79static void
80test_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
91static void
92test_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
112static void
113test_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
138static void
139test_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
164static void
165test_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
180static void
181test_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
194static void
195test_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
203static void
204test_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
219void
220unique_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