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