/* "True" vs "False" vs "Unknown".
Copyright (C) 2019-2020 Free Software Foundation, Inc.
Contributed by David Malcolm <dmalcolm@redhat.com>.
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
<http://www.gnu.org/licenses/>. */
#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 */