1 /* "True" vs "False" vs "Unknown". 2 Copyright (C) 2019-2020 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