18dd4bdcdSmrg /* Unit tests for unique-ptr.h.
2*0bfacb9bSmrg    Copyright (C) 2017-2020 Free Software Foundation, Inc.
38dd4bdcdSmrg 
48dd4bdcdSmrg This file is part of GCC.
58dd4bdcdSmrg 
68dd4bdcdSmrg GCC is free software; you can redistribute it and/or modify it under
78dd4bdcdSmrg the terms of the GNU General Public License as published by the Free
88dd4bdcdSmrg Software Foundation; either version 3, or (at your option) any later
98dd4bdcdSmrg version.
108dd4bdcdSmrg 
118dd4bdcdSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
128dd4bdcdSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
138dd4bdcdSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
148dd4bdcdSmrg for more details.
158dd4bdcdSmrg 
168dd4bdcdSmrg You should have received a copy of the GNU General Public License
178dd4bdcdSmrg along with GCC; see the file COPYING3.  If not see
188dd4bdcdSmrg <http://www.gnu.org/licenses/>.  */
198dd4bdcdSmrg 
208dd4bdcdSmrg #include "config.h"
218dd4bdcdSmrg #define INCLUDE_UNIQUE_PTR
228dd4bdcdSmrg #include "system.h"
238dd4bdcdSmrg #include "coretypes.h"
248dd4bdcdSmrg #include "selftest.h"
258dd4bdcdSmrg 
268dd4bdcdSmrg #if CHECKING_P
278dd4bdcdSmrg 
288dd4bdcdSmrg namespace selftest {
298dd4bdcdSmrg 
308dd4bdcdSmrg namespace {
318dd4bdcdSmrg 
328dd4bdcdSmrg /* A class for counting ctor and dtor invocations.  */
338dd4bdcdSmrg 
34*0bfacb9bSmrg class stats
358dd4bdcdSmrg {
36*0bfacb9bSmrg public:
stats()378dd4bdcdSmrg   stats () : ctor_count (0), dtor_count (0) {}
388dd4bdcdSmrg 
398dd4bdcdSmrg   int ctor_count;
408dd4bdcdSmrg   int dtor_count;
418dd4bdcdSmrg };
428dd4bdcdSmrg 
438dd4bdcdSmrg /* A class that uses "stats" to track its ctor and dtor invocations.  */
448dd4bdcdSmrg 
458dd4bdcdSmrg class foo
468dd4bdcdSmrg {
478dd4bdcdSmrg public:
foo(stats & s)488dd4bdcdSmrg   foo (stats &s) : m_s (s) { ++m_s.ctor_count; }
~foo()498dd4bdcdSmrg   ~foo () { ++m_s.dtor_count; }
508dd4bdcdSmrg 
example_method() const518dd4bdcdSmrg   int example_method () const { return 42; }
528dd4bdcdSmrg 
538dd4bdcdSmrg private:
548dd4bdcdSmrg   foo (const foo&);
558dd4bdcdSmrg   foo & operator= (const foo &);
568dd4bdcdSmrg 
578dd4bdcdSmrg private:
588dd4bdcdSmrg   stats &m_s;
598dd4bdcdSmrg };
608dd4bdcdSmrg 
618dd4bdcdSmrg /* A struct for testing unique_ptr<T[]>.  */
628dd4bdcdSmrg 
63*0bfacb9bSmrg class has_default_ctor
648dd4bdcdSmrg {
65*0bfacb9bSmrg public:
has_default_ctor()668dd4bdcdSmrg   has_default_ctor () : m_field (42) {}
678dd4bdcdSmrg   int m_field;
688dd4bdcdSmrg };
698dd4bdcdSmrg 
708dd4bdcdSmrg /* A dummy struct for testing unique_xmalloc_ptr.  */
718dd4bdcdSmrg 
728dd4bdcdSmrg struct dummy
738dd4bdcdSmrg {
748dd4bdcdSmrg   int field;
758dd4bdcdSmrg };
768dd4bdcdSmrg 
778dd4bdcdSmrg } // anonymous namespace
788dd4bdcdSmrg 
798dd4bdcdSmrg /* Verify that the default ctor inits ptrs to NULL.  */
808dd4bdcdSmrg 
818dd4bdcdSmrg static void
test_null_ptr()828dd4bdcdSmrg test_null_ptr ()
838dd4bdcdSmrg {
848dd4bdcdSmrg   gnu::unique_ptr<void *> p;
858dd4bdcdSmrg   ASSERT_EQ (NULL, p);
868dd4bdcdSmrg 
878dd4bdcdSmrg   gnu::unique_xmalloc_ptr<void *> q;
888dd4bdcdSmrg   ASSERT_EQ (NULL, q);
898dd4bdcdSmrg }
908dd4bdcdSmrg 
918dd4bdcdSmrg /* Verify that deletion happens when a unique_ptr goes out of scope.  */
928dd4bdcdSmrg 
938dd4bdcdSmrg static void
test_implicit_deletion()948dd4bdcdSmrg test_implicit_deletion ()
958dd4bdcdSmrg {
968dd4bdcdSmrg   stats s;
978dd4bdcdSmrg   ASSERT_EQ (0, s.ctor_count);
988dd4bdcdSmrg   ASSERT_EQ (0, s.dtor_count);
998dd4bdcdSmrg 
1008dd4bdcdSmrg   {
1018dd4bdcdSmrg     gnu::unique_ptr<foo> f (new foo (s));
1028dd4bdcdSmrg     ASSERT_NE (NULL, f);
1038dd4bdcdSmrg     ASSERT_EQ (1, s.ctor_count);
1048dd4bdcdSmrg     ASSERT_EQ (0, s.dtor_count);
1058dd4bdcdSmrg   }
1068dd4bdcdSmrg 
1078dd4bdcdSmrg   /* Verify that the foo was implicitly deleted.  */
1088dd4bdcdSmrg   ASSERT_EQ (1, s.ctor_count);
1098dd4bdcdSmrg   ASSERT_EQ (1, s.dtor_count);
1108dd4bdcdSmrg }
1118dd4bdcdSmrg 
1128dd4bdcdSmrg /* Verify that we can assign to a NULL unique_ptr.  */
1138dd4bdcdSmrg 
1148dd4bdcdSmrg static void
test_overwrite_of_null()1158dd4bdcdSmrg test_overwrite_of_null ()
1168dd4bdcdSmrg {
1178dd4bdcdSmrg   stats s;
1188dd4bdcdSmrg   ASSERT_EQ (0, s.ctor_count);
1198dd4bdcdSmrg   ASSERT_EQ (0, s.dtor_count);
1208dd4bdcdSmrg 
1218dd4bdcdSmrg   {
1228dd4bdcdSmrg     gnu::unique_ptr<foo> f;
1238dd4bdcdSmrg     ASSERT_EQ (NULL, f);
1248dd4bdcdSmrg     ASSERT_EQ (0, s.ctor_count);
1258dd4bdcdSmrg     ASSERT_EQ (0, s.dtor_count);
1268dd4bdcdSmrg 
1278dd4bdcdSmrg     /* Overwrite with a non-NULL value.  */
1288dd4bdcdSmrg     f = gnu::unique_ptr<foo> (new foo (s));
1298dd4bdcdSmrg     ASSERT_EQ (1, s.ctor_count);
1308dd4bdcdSmrg     ASSERT_EQ (0, s.dtor_count);
1318dd4bdcdSmrg   }
1328dd4bdcdSmrg 
1338dd4bdcdSmrg   /* Verify that the foo is implicitly deleted.  */
1348dd4bdcdSmrg   ASSERT_EQ (1, s.ctor_count);
1358dd4bdcdSmrg   ASSERT_EQ (1, s.dtor_count);
1368dd4bdcdSmrg }
1378dd4bdcdSmrg 
1388dd4bdcdSmrg /* Verify that we can assign to a non-NULL unique_ptr.  */
1398dd4bdcdSmrg 
1408dd4bdcdSmrg static void
test_overwrite_of_non_null()1418dd4bdcdSmrg test_overwrite_of_non_null ()
1428dd4bdcdSmrg {
1438dd4bdcdSmrg   stats s;
1448dd4bdcdSmrg   ASSERT_EQ (0, s.ctor_count);
1458dd4bdcdSmrg   ASSERT_EQ (0, s.dtor_count);
1468dd4bdcdSmrg 
1478dd4bdcdSmrg   {
1488dd4bdcdSmrg     gnu::unique_ptr<foo> f (new foo (s));
1498dd4bdcdSmrg     ASSERT_NE (NULL, f);
1508dd4bdcdSmrg     ASSERT_EQ (1, s.ctor_count);
1518dd4bdcdSmrg     ASSERT_EQ (0, s.dtor_count);
1528dd4bdcdSmrg 
1538dd4bdcdSmrg     /* Overwrite with a different value.  */
1548dd4bdcdSmrg     f = gnu::unique_ptr<foo> (new foo (s));
1558dd4bdcdSmrg     ASSERT_EQ (2, s.ctor_count);
1568dd4bdcdSmrg     ASSERT_EQ (1, s.dtor_count);
1578dd4bdcdSmrg   }
1588dd4bdcdSmrg 
1598dd4bdcdSmrg   /* Verify that the 2nd foo was implicitly deleted.  */
1608dd4bdcdSmrg   ASSERT_EQ (2, s.ctor_count);
1618dd4bdcdSmrg   ASSERT_EQ (2, s.dtor_count);
1628dd4bdcdSmrg }
1638dd4bdcdSmrg 
1648dd4bdcdSmrg /* Verify that unique_ptr's overloaded ops work.  */
1658dd4bdcdSmrg 
1668dd4bdcdSmrg static void
test_overloaded_ops()1678dd4bdcdSmrg test_overloaded_ops ()
1688dd4bdcdSmrg {
1698dd4bdcdSmrg   stats s;
1708dd4bdcdSmrg   gnu::unique_ptr<foo> f (new foo (s));
1718dd4bdcdSmrg   ASSERT_EQ (42, f->example_method ());
1728dd4bdcdSmrg   ASSERT_EQ (42, (*f).example_method ());
1738dd4bdcdSmrg   ASSERT_EQ (f, f);
1748dd4bdcdSmrg   ASSERT_NE (NULL, f.get ());
1758dd4bdcdSmrg 
1768dd4bdcdSmrg   gnu::unique_ptr<foo> g (new foo (s));
1778dd4bdcdSmrg   ASSERT_NE (f, g);
1788dd4bdcdSmrg }
1798dd4bdcdSmrg 
1808dd4bdcdSmrg /* Verify that the gnu::unique_ptr specialization for T[] works.  */
1818dd4bdcdSmrg 
1828dd4bdcdSmrg static void
test_array_new()1838dd4bdcdSmrg test_array_new ()
1848dd4bdcdSmrg {
1858dd4bdcdSmrg   const int num = 10;
1868dd4bdcdSmrg   gnu::unique_ptr<has_default_ctor[]> p (new has_default_ctor[num]);
1878dd4bdcdSmrg   ASSERT_NE (NULL, p.get ());
1888dd4bdcdSmrg   /* Verify that operator[] works, and that the default ctor was called
1898dd4bdcdSmrg      on each element.  */
1908dd4bdcdSmrg   for (int i = 0; i < num; i++)
1918dd4bdcdSmrg     ASSERT_EQ (42, p[i].m_field);
1928dd4bdcdSmrg }
1938dd4bdcdSmrg 
1948dd4bdcdSmrg /* Verify that gnu::unique_xmalloc_ptr works.  */
1958dd4bdcdSmrg 
1968dd4bdcdSmrg static void
test_xmalloc()1978dd4bdcdSmrg test_xmalloc ()
1988dd4bdcdSmrg {
1998dd4bdcdSmrg   gnu::unique_xmalloc_ptr<dummy> p (XNEW (dummy));
2008dd4bdcdSmrg   ASSERT_NE (NULL, p.get ());
2018dd4bdcdSmrg }
2028dd4bdcdSmrg 
2038dd4bdcdSmrg /* Verify the gnu::unique_xmalloc_ptr specialization for T[].  */
2048dd4bdcdSmrg 
2058dd4bdcdSmrg static void
test_xmalloc_array()2068dd4bdcdSmrg test_xmalloc_array ()
2078dd4bdcdSmrg {
2088dd4bdcdSmrg   const int num = 10;
2098dd4bdcdSmrg   gnu::unique_xmalloc_ptr<dummy[]> p (XNEWVEC (dummy, num));
2108dd4bdcdSmrg   ASSERT_NE (NULL, p.get ());
2118dd4bdcdSmrg 
2128dd4bdcdSmrg   /* Verify that operator[] works.  */
2138dd4bdcdSmrg   for (int i = 0; i < num; i++)
2148dd4bdcdSmrg     p[i].field = 42;
2158dd4bdcdSmrg   for (int i = 0; i < num; i++)
2168dd4bdcdSmrg     ASSERT_EQ (42, p[i].field);
2178dd4bdcdSmrg }
2188dd4bdcdSmrg 
2198dd4bdcdSmrg /* Run all of the selftests within this file.  */
2208dd4bdcdSmrg 
2218dd4bdcdSmrg void
unique_ptr_tests_cc_tests()2228dd4bdcdSmrg unique_ptr_tests_cc_tests ()
2238dd4bdcdSmrg {
2248dd4bdcdSmrg   test_null_ptr ();
2258dd4bdcdSmrg   test_implicit_deletion ();
2268dd4bdcdSmrg   test_overwrite_of_null ();
2278dd4bdcdSmrg   test_overwrite_of_non_null ();
2288dd4bdcdSmrg   test_overloaded_ops ();
2298dd4bdcdSmrg   test_array_new ();
2308dd4bdcdSmrg   test_xmalloc ();
2318dd4bdcdSmrg   test_xmalloc_array ();
2328dd4bdcdSmrg }
2338dd4bdcdSmrg 
2348dd4bdcdSmrg } // namespace selftest
2358dd4bdcdSmrg 
2368dd4bdcdSmrg #endif /* #if CHECKING_P */
237