1/* "True" vs "False" vs "Unknown".
2 Copyright (C) 2019-2023 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tristate.h"
25#include "selftest.h"
26
27const char *
28tristate::as_string () const
29{
30 switch (m_value)
31 {
32 default:
33 gcc_unreachable ();
34 case TS_UNKNOWN:
35 return "UNKNOWN";
36 case TS_TRUE:
37 return "TRUE";
38 case TS_FALSE:
39 return "FALSE";
40 }
41}
42
43tristate
44tristate::not_ () const
45{
46 switch (m_value)
47 {
48 default:
49 gcc_unreachable ();
50 case TS_UNKNOWN:
51 return tristate (TS_UNKNOWN);
52 case TS_TRUE:
53 return tristate (TS_FALSE);
54 case TS_FALSE:
55 return tristate (TS_TRUE);
56 }
57}
58
59tristate
60tristate::or_ (tristate other) const
61{
62 switch (m_value)
63 {
64 default:
65 gcc_unreachable ();
66 case TS_UNKNOWN:
67 if (other.is_true ())
68 return tristate (TS_TRUE);
69 else
70 return tristate (TS_UNKNOWN);
71 case TS_FALSE:
72 return other;
73 case TS_TRUE:
74 return tristate (TS_TRUE);
75 }
76}
77
78tristate
79tristate::and_ (tristate other) const
80{
81 switch (m_value)
82 {
83 default:
84 gcc_unreachable ();
85 case TS_UNKNOWN:
86 if (other.is_false ())
87 return tristate (TS_FALSE);
88 else
89 return tristate (TS_UNKNOWN);
90 case TS_TRUE:
91 return other;
92 case TS_FALSE:
93 return tristate (TS_FALSE);
94 }
95}
96
97#if CHECKING_P
98
99namespace selftest {
100
101#define ASSERT_TRISTATE_TRUE(TRISTATE) \
102 SELFTEST_BEGIN_STMT \
103 ASSERT_EQ (TRISTATE, tristate (tristate::TS_TRUE)); \
104 SELFTEST_END_STMT
105
106#define ASSERT_TRISTATE_FALSE(TRISTATE) \
107 SELFTEST_BEGIN_STMT \
108 ASSERT_EQ (TRISTATE, tristate (tristate::TS_FALSE)); \
109 SELFTEST_END_STMT
110
111#define ASSERT_TRISTATE_UNKNOWN(TRISTATE) \
112 SELFTEST_BEGIN_STMT \
113 ASSERT_EQ (TRISTATE, tristate (tristate::TS_UNKNOWN)); \
114 SELFTEST_END_STMT
115
116/* Test tristate's ctors, along with is_*, as_string, operator==, and
117 operator!=. */
118
119static void
120test_ctors ()
121{
122 tristate u (tristate::TS_UNKNOWN);
123 ASSERT_FALSE (u.is_known ());
124 ASSERT_FALSE (u.is_true ());
125 ASSERT_FALSE (u.is_false ());
126 ASSERT_STREQ (u.as_string (), "UNKNOWN");
127
128 tristate t (tristate::TS_TRUE);
129 ASSERT_TRUE (t.is_known ());
130 ASSERT_TRUE (t.is_true ());
131 ASSERT_FALSE (t.is_false ());
132 ASSERT_STREQ (t.as_string (), "TRUE");
133
134 tristate f (tristate::TS_FALSE);
135 ASSERT_TRUE (f.is_known ());
136 ASSERT_FALSE (f.is_true ());
137 ASSERT_TRUE (f.is_false ());
138 ASSERT_STREQ (f.as_string (), "FALSE");
139
140 ASSERT_EQ (u, u);
141 ASSERT_EQ (t, t);
142 ASSERT_EQ (f, f);
143 ASSERT_NE (u, t);
144 ASSERT_NE (u, f);
145 ASSERT_NE (t, f);
146
147 tristate t2 (true);
148 ASSERT_TRUE (t2.is_true ());
149 ASSERT_EQ (t, t2);
150
151 tristate f2 (false);
152 ASSERT_TRUE (f2.is_false ());
153 ASSERT_EQ (f, f2);
154
155 tristate u2 (tristate::unknown ());
156 ASSERT_TRUE (!u2.is_known ());
157 ASSERT_EQ (u, u2);
158}
159
160/* Test && on tristate instances. */
161
162static void
163test_and ()
164{
165 ASSERT_TRISTATE_UNKNOWN (tristate::unknown () && tristate::unknown ());
166
167 ASSERT_TRISTATE_FALSE (tristate (false) && tristate (false));
168 ASSERT_TRISTATE_FALSE (tristate (false) && tristate (true));
169 ASSERT_TRISTATE_FALSE (tristate (true) && tristate (false));
170 ASSERT_TRISTATE_TRUE (tristate (true) && tristate (true));
171
172 ASSERT_TRISTATE_UNKNOWN (tristate::unknown () && tristate (true));
173 ASSERT_TRISTATE_UNKNOWN (tristate (true) && tristate::unknown ());
174
175 ASSERT_TRISTATE_FALSE (tristate::unknown () && tristate (false));
176 ASSERT_TRISTATE_FALSE (tristate (false) && tristate::unknown ());
177}
178
179/* Test || on tristate instances. */
180
181static void
182test_or ()
183{
184 ASSERT_TRISTATE_UNKNOWN (tristate::unknown () || tristate::unknown ());
185
186 ASSERT_TRISTATE_FALSE (tristate (false) || tristate (false));
187 ASSERT_TRISTATE_TRUE (tristate (false) || tristate (true));
188 ASSERT_TRISTATE_TRUE (tristate (true) || tristate (false));
189 ASSERT_TRISTATE_TRUE (tristate (true) || tristate (true));
190
191 ASSERT_TRISTATE_TRUE (tristate::unknown () || tristate (true));
192 ASSERT_TRISTATE_TRUE (tristate (true) || tristate::unknown ());
193
194 ASSERT_TRISTATE_UNKNOWN (tristate::unknown () || tristate (false));
195 ASSERT_TRISTATE_UNKNOWN (tristate (false) || tristate::unknown ());
196}
197
198/* Test ! on tristate instances. */
199
200static void
201test_not ()
202{
203 ASSERT_TRISTATE_UNKNOWN (!tristate::unknown ());
204 ASSERT_TRISTATE_FALSE (!tristate (true));
205 ASSERT_TRISTATE_TRUE (!tristate (false));
206}
207
208/* Run all of the selftests within this file. */
209
210void
211tristate_cc_tests ()
212{
213 test_ctors ();
214 test_and ();
215 test_or ();
216 test_not ();
217}
218
219} // namespace selftest
220
221#endif /* CHECKING_P */
222

source code of gcc/tristate.cc