/* "True" vs "False" vs "Unknown". Copyright (C) 2019-2020 Free Software Foundation, Inc. Contributed by David Malcolm . This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ #include "config.h" #include "system.h" #include "coretypes.h" #include "tristate.h" #include "selftest.h" const char * tristate::as_string () const { switch (m_value) { default: gcc_unreachable (); case TS_UNKNOWN: return "UNKNOWN"; case TS_TRUE: return "TRUE"; case TS_FALSE: return "FALSE"; } } tristate tristate::not_ () const { switch (m_value) { default: gcc_unreachable (); case TS_UNKNOWN: return tristate (TS_UNKNOWN); case TS_TRUE: return tristate (TS_FALSE); case TS_FALSE: return tristate (TS_TRUE); } } tristate tristate::or_ (tristate other) const { switch (m_value) { default: gcc_unreachable (); case TS_UNKNOWN: if (other.is_true ()) return tristate (TS_TRUE); else return tristate (TS_UNKNOWN); case TS_FALSE: return other; case TS_TRUE: return tristate (TS_TRUE); } } tristate tristate::and_ (tristate other) const { switch (m_value) { default: gcc_unreachable (); case TS_UNKNOWN: if (other.is_false ()) return tristate (TS_FALSE); else return tristate (TS_UNKNOWN); case TS_TRUE: return other; case TS_FALSE: return tristate (TS_FALSE); } } #if CHECKING_P namespace selftest { #define ASSERT_TRISTATE_TRUE(TRISTATE) \ SELFTEST_BEGIN_STMT \ ASSERT_EQ (TRISTATE, tristate (tristate::TS_TRUE)); \ SELFTEST_END_STMT #define ASSERT_TRISTATE_FALSE(TRISTATE) \ SELFTEST_BEGIN_STMT \ ASSERT_EQ (TRISTATE, tristate (tristate::TS_FALSE)); \ SELFTEST_END_STMT #define ASSERT_TRISTATE_UNKNOWN(TRISTATE) \ SELFTEST_BEGIN_STMT \ ASSERT_EQ (TRISTATE, tristate (tristate::TS_UNKNOWN)); \ SELFTEST_END_STMT /* Test tristate's ctors, along with is_*, as_string, operator==, and operator!=. */ static void test_ctors () { tristate u (tristate::TS_UNKNOWN); ASSERT_FALSE (u.is_known ()); ASSERT_FALSE (u.is_true ()); ASSERT_FALSE (u.is_false ()); ASSERT_STREQ (u.as_string (), "UNKNOWN"); tristate t (tristate::TS_TRUE); ASSERT_TRUE (t.is_known ()); ASSERT_TRUE (t.is_true ()); ASSERT_FALSE (t.is_false ()); ASSERT_STREQ (t.as_string (), "TRUE"); tristate f (tristate::TS_FALSE); ASSERT_TRUE (f.is_known ()); ASSERT_FALSE (f.is_true ()); ASSERT_TRUE (f.is_false ()); ASSERT_STREQ (f.as_string (), "FALSE"); ASSERT_EQ (u, u); ASSERT_EQ (t, t); ASSERT_EQ (f, f); ASSERT_NE (u, t); ASSERT_NE (u, f); ASSERT_NE (t, f); tristate t2 (true); ASSERT_TRUE (t2.is_true ()); ASSERT_EQ (t, t2); tristate f2 (false); ASSERT_TRUE (f2.is_false ()); ASSERT_EQ (f, f2); tristate u2 (tristate::unknown ()); ASSERT_TRUE (!u2.is_known ()); ASSERT_EQ (u, u2); } /* Test && on tristate instances. */ static void test_and () { ASSERT_TRISTATE_UNKNOWN (tristate::unknown () && tristate::unknown ()); ASSERT_TRISTATE_FALSE (tristate (false) && tristate (false)); ASSERT_TRISTATE_FALSE (tristate (false) && tristate (true)); ASSERT_TRISTATE_FALSE (tristate (true) && tristate (false)); ASSERT_TRISTATE_TRUE (tristate (true) && tristate (true)); ASSERT_TRISTATE_UNKNOWN (tristate::unknown () && tristate (true)); ASSERT_TRISTATE_UNKNOWN (tristate (true) && tristate::unknown ()); ASSERT_TRISTATE_FALSE (tristate::unknown () && tristate (false)); ASSERT_TRISTATE_FALSE (tristate (false) && tristate::unknown ()); } /* Test || on tristate instances. */ static void test_or () { ASSERT_TRISTATE_UNKNOWN (tristate::unknown () || tristate::unknown ()); ASSERT_TRISTATE_FALSE (tristate (false) || tristate (false)); ASSERT_TRISTATE_TRUE (tristate (false) || tristate (true)); ASSERT_TRISTATE_TRUE (tristate (true) || tristate (false)); ASSERT_TRISTATE_TRUE (tristate (true) || tristate (true)); ASSERT_TRISTATE_TRUE (tristate::unknown () || tristate (true)); ASSERT_TRISTATE_TRUE (tristate (true) || tristate::unknown ()); ASSERT_TRISTATE_UNKNOWN (tristate::unknown () || tristate (false)); ASSERT_TRISTATE_UNKNOWN (tristate (false) || tristate::unknown ()); } /* Test ! on tristate instances. */ static void test_not () { ASSERT_TRISTATE_UNKNOWN (!tristate::unknown ()); ASSERT_TRISTATE_FALSE (!tristate (true)); ASSERT_TRISTATE_TRUE (!tristate (false)); } /* Run all of the selftests within this file. */ void tristate_cc_tests () { test_ctors (); test_and (); test_or (); test_not (); } } // namespace selftest #endif /* CHECKING_P */