1 | /* "True" vs "False" vs "Unknown". |
2 | Copyright (C) 2019-2023 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 | tristate::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 | |
43 | tristate |
44 | tristate::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 | |
59 | tristate |
60 | tristate::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 | |
78 | tristate |
79 | tristate::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 | |
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 | test_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 | |
162 | static void |
163 | test_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 | |
181 | static void |
182 | test_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 | |
200 | static void |
201 | test_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 | |
210 | void |
211 | tristate_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 | |