blob: dc200cf572bfec30f904e0754f89984aff1b18af [file] [log] [blame]
Howard Hinnant4a889712011-05-24 22:01:161//===----------------------------- test_guard.cpp -------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Howard Hinnant4a889712011-05-24 22:01:1610#include "cxxabi.h"
11
12#include <cassert>
Eric Fiselier559f8672014-11-24 22:42:0313
Asiri Rathnayake7c98baa2016-09-21 09:09:3214#ifndef _LIBCXXABI_HAS_NO_THREADS
Nick Lewycky6fde1502011-06-04 18:01:2415#include <thread>
Eric Fiselier559f8672014-11-24 22:42:0316#endif
Howard Hinnant4a889712011-05-24 22:01:1617
Nick Lewycky6fde1502011-06-04 18:01:2418// Ensure that we initialize each variable once and only once.
Howard Hinnant4a889712011-05-24 22:01:1619namespace test1 {
20 static int run_count = 0;
21 int increment() {
22 ++run_count;
23 return 0;
24 }
25 void helper() {
26 static int a = increment();
Eric Fiseliera140cba2016-12-24 00:37:1327 ((void)a);
Howard Hinnant4a889712011-05-24 22:01:1628 }
29 void test() {
Eric Fiseliera140cba2016-12-24 00:37:1330 static int a = increment(); ((void)a);
Howard Hinnant4a889712011-05-24 22:01:1631 assert(run_count == 1);
Eric Fiseliera140cba2016-12-24 00:37:1332 static int b = increment(); ((void)b);
Howard Hinnant4a889712011-05-24 22:01:1633 assert(run_count == 2);
34 helper();
35 assert(run_count == 3);
36 helper();
37 assert(run_count == 3);
38 }
39}
40
Nick Lewycky6fde1502011-06-04 18:01:2441// When initialization fails, ensure that we try to initialize it again next
42// time.
Howard Hinnant4a889712011-05-24 22:01:1643namespace test2 {
Asiri Rathnayake57e446d2016-05-31 12:01:3244#ifndef LIBCXXABI_HAS_NO_EXCEPTIONS
Howard Hinnant4a889712011-05-24 22:01:1645 static int run_count = 0;
46 int increment() {
47 ++run_count;
48 throw 0;
49 }
50 void helper() {
51 try {
52 static int a = increment();
Eric Fiseliera140cba2016-12-24 00:37:1353 assert(false);
54 ((void)a);
Howard Hinnant4a889712011-05-24 22:01:1655 } catch (...) {}
56 }
57 void test() {
58 helper();
59 assert(run_count == 1);
60 helper();
61 assert(run_count == 2);
62 }
Asiri Rathnayake57e446d2016-05-31 12:01:3263#else
64 void test() {}
65#endif
Howard Hinnant4a889712011-05-24 22:01:1666}
67
Nick Lewycky6fde1502011-06-04 18:01:2468// Check that we can initialize a second value while initializing a first.
69namespace test3 {
70 int zero() {
71 return 0;
72 }
73
74 int one() {
Eric Fiseliera140cba2016-12-24 00:37:1375 static int b = zero(); ((void)b);
Nick Lewycky6fde1502011-06-04 18:01:2476 return 0;
77 }
78
79 void test() {
Eric Fiseliera140cba2016-12-24 00:37:1380 static int a = one(); ((void)a);
Nick Lewycky6fde1502011-06-04 18:01:2481 }
82}
83
Asiri Rathnayake7c98baa2016-09-21 09:09:3284#ifndef _LIBCXXABI_HAS_NO_THREADS
Nick Lewycky6fde1502011-06-04 18:01:2485// A simple thread test of two threads racing to initialize a variable. This
86// isn't guaranteed to catch any particular threading problems.
87namespace test4 {
88 static int run_count = 0;
89 int increment() {
90 ++run_count;
Howard Hinnant575498b2011-06-07 19:56:4991 return 0;
Nick Lewycky6fde1502011-06-04 18:01:2492 }
93
94 void helper() {
Eric Fiseliera140cba2016-12-24 00:37:1395 static int a = increment(); ((void)a);
Nick Lewycky6fde1502011-06-04 18:01:2496 }
97
98 void test() {
99 std::thread t1(helper), t2(helper);
100 t1.join();
101 t2.join();
Howard Hinnant575498b2011-06-07 19:56:49102 assert(run_count == 1);
Nick Lewycky6fde1502011-06-04 18:01:24103 }
104}
105
106// Check that we don't re-initialize a static variable even when it's
107// encountered from two different threads.
108namespace test5 {
109 static int run_count = 0;
110 int zero() {
111 ++run_count;
112 return 0;
113 }
114
115 int one() {
Eric Fiseliera140cba2016-12-24 00:37:13116 static int b = zero(); ((void)b);
Howard Hinnant575498b2011-06-07 19:56:49117 return 0;
Nick Lewycky6fde1502011-06-04 18:01:24118 }
119
120 void another_helper() {
Eric Fiseliera140cba2016-12-24 00:37:13121 static int a = one(); ((void)a);
Nick Lewycky6fde1502011-06-04 18:01:24122 }
123
124 void helper() {
Eric Fiseliera140cba2016-12-24 00:37:13125 static int a = one(); ((void)a);
Howard Hinnant575498b2011-06-07 19:56:49126 std::thread t(another_helper);
127 t.join();
Nick Lewycky6fde1502011-06-04 18:01:24128 }
129
130 void test() {
131 std::thread t(helper);
132 t.join();
Howard Hinnant575498b2011-06-07 19:56:49133 assert(run_count == 1);
Nick Lewycky6fde1502011-06-04 18:01:24134 }
135}
Asiri Rathnayake7c98baa2016-09-21 09:09:32136#endif /* _LIBCXXABI_HAS_NO_THREADS */
Nick Lewycky6fde1502011-06-04 18:01:24137
Howard Hinnant4a889712011-05-24 22:01:16138int main()
139{
140 test1::test();
141 test2::test();
Nick Lewycky6fde1502011-06-04 18:01:24142 test3::test();
Asiri Rathnayake7c98baa2016-09-21 09:09:32143#ifndef _LIBCXXABI_HAS_NO_THREADS
Nick Lewycky6fde1502011-06-04 18:01:24144 test4::test();
145 test5::test();
Eric Fiselier559f8672014-11-24 22:42:03146#endif
Howard Hinnant4a889712011-05-24 22:01:16147}