Line data Source code
1 : /* "True" vs "False" vs "Unknown".
2 : Copyright (C) 2019-2026 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 4539 : tristate::as_string () const
29 : {
30 4539 : switch (m_value)
31 : {
32 0 : default:
33 0 : gcc_unreachable ();
34 : case TS_UNKNOWN:
35 : return "UNKNOWN";
36 3225 : case TS_TRUE:
37 3225 : return "TRUE";
38 246 : case TS_FALSE:
39 246 : 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 2792 : tristate::and_ (tristate other) const
80 : {
81 2792 : switch (m_value)
82 : {
83 0 : default:
84 0 : gcc_unreachable ();
85 287 : case TS_UNKNOWN:
86 287 : if (other.is_false ())
87 74 : return tristate (TS_FALSE);
88 : else
89 213 : return tristate (TS_UNKNOWN);
90 614 : case TS_TRUE:
91 614 : return other;
92 1891 : case TS_FALSE:
93 1891 : 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 */
|