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