From 496973d00ad71b8cf1128f030d4dfc9e9d4bd077 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 21 Jun 2019 17:11:04 -0400
Subject: [PATCH 44/47] FIXME: add tristate.cc selftests

---
 gcc/analyzer/analyzer-plugin.cc |   1 +
 gcc/analyzer/analyzer.h         |   1 +
 gcc/analyzer/sm.h               |   6 +--
 gcc/analyzer/tristate.cc        | 114 ++++++++++++++++++++++++++++++++++++++++
 gcc/analyzer/tristate.h         |   6 +++
 5 files changed, 125 insertions(+), 3 deletions(-)

diff --git a/gcc/analyzer/analyzer-plugin.cc b/gcc/analyzer/analyzer-plugin.cc
index f51c085..5dc89bb 100644
--- a/gcc/analyzer/analyzer-plugin.cc
+++ b/gcc/analyzer/analyzer-plugin.cc
@@ -45,6 +45,7 @@ analyzer_selftests (void */*gcc_data*/, void */*user_data*/)
   analyzer_impl_4_cc_tests ();
   analyzer_path_state_cc_tests ();
   analyzer_region_model_cc_tests ();
+  analyzer_tristate_cc_tests ();
 }
 
 } /* end of namespace selftest.  */
diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index 5a2ce06..0115455 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -68,6 +68,7 @@ extern void analyzer_impl_2_cc_tests ();
 extern void analyzer_impl_4_cc_tests ();
 extern void analyzer_path_state_cc_tests ();
 extern void analyzer_region_model_cc_tests ();
+extern void analyzer_tristate_cc_tests ();
 
 } /* end of namespace selftest.  */
 
diff --git a/gcc/analyzer/sm.h b/gcc/analyzer/sm.h
index 1b9be15..300441d 100644
--- a/gcc/analyzer/sm.h
+++ b/gcc/analyzer/sm.h
@@ -18,8 +18,8 @@ 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/>.  */
 
-#ifndef GCC_ANALYZER_HARDCODED_STATE_MACHINE_H
-#define GCC_ANALYZER_HARDCODED_STATE_MACHINE_H
+#ifndef GCC_ANALYZER_SM_H
+#define GCC_ANALYZER_SM_H
 
 #include "analyzer-logging.h"
 #include "diagnostic-metadata.h"
@@ -582,4 +582,4 @@ private:
   state_t m_start;
 };
 
-#endif /* GCC_ANALYZER_HARDCODED_STATE_MACHINE_H */
+#endif /* GCC_ANALYZER_SM_H */
diff --git a/gcc/analyzer/tristate.cc b/gcc/analyzer/tristate.cc
index 37b200c..08e3f7e 100644
--- a/gcc/analyzer/tristate.cc
+++ b/gcc/analyzer/tristate.cc
@@ -3,6 +3,7 @@
 #include "system.h"
 #include "coretypes.h"
 #include "tristate.h"
+#include "selftest.h"
 
 const char *
 tristate::as_string () const
@@ -65,3 +66,116 @@ tristate::and_ (tristate other) const
       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
+
+/* FIXME.  */
+
+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);
+}
+
+/* FIXME.  */
+
+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 ());
+}
+
+/* FIXME.  */
+
+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 ());
+}
+
+/* FIXME.  */
+
+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
+analyzer_tristate_cc_tests ()
+{
+  test_ctors ();
+  test_and ();
+  test_or ();
+  test_not ();
+}
+
+} // namespace selftest
+
+#endif /* CHECKING_P */
diff --git a/gcc/analyzer/tristate.h b/gcc/analyzer/tristate.h
index 3e91734..4678066 100644
--- a/gcc/analyzer/tristate.h
+++ b/gcc/analyzer/tristate.h
@@ -31,6 +31,7 @@ class tristate {
 
   tristate (enum value val) : m_value (val) {}
   tristate (bool val) : m_value (val ? TS_TRUE : TS_FALSE) {}
+  static tristate unknown () { return tristate (TS_UNKNOWN); }
 
   const char *as_string () const;
 
@@ -47,6 +48,11 @@ class tristate {
     return m_value == other.m_value;
   }
 
+  bool operator!= (const tristate &other) const
+  {
+    return m_value != other.m_value;
+  }
+
  private:
   enum value m_value;
 };
-- 
1.8.5.3

