1 /* "True" vs "False" vs "Unknown".
2    Copyright (C) 2019-2021 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 *
as_string() const28 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
not_() const44 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
or_(tristate other) const60 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
and_(tristate other) const79 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
test_ctors()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
test_and()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
test_or()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
test_not()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
tristate_cc_tests()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