public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: David Malcolm <dmalcolm@redhat.com>
To: gcc-patches@gcc.gnu.org
Cc: David Malcolm <dmalcolm@redhat.com>
Subject: [PATCH 24/45] analyzer: new files: tristate.{cc|h}
Date: Fri, 13 Dec 2019 18:12:00 -0000	[thread overview]
Message-ID: <20191213181134.1830-25-dmalcolm@redhat.com> (raw)
In-Reply-To: <20191213181134.1830-1-dmalcolm@redhat.com>

Changed in v4:
- moved from gcc/analyzer to gcc

gcc/ChangeLog:
	* tristate.cc: New file.
	* tristate.h: New file.
---
 gcc/tristate.cc | 221 ++++++++++++++++++++++++++++++++++++++++++++++++
 gcc/tristate.h  |  82 ++++++++++++++++++
 2 files changed, 303 insertions(+)
 create mode 100644 gcc/tristate.cc
 create mode 100644 gcc/tristate.h

diff --git a/gcc/tristate.cc b/gcc/tristate.cc
new file mode 100644
index 000000000000..78217f196804
--- /dev/null
+++ b/gcc/tristate.cc
@@ -0,0 +1,221 @@
+/* "True" vs "False" vs "Unknown".
+   Copyright (C) 2019 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 */
diff --git a/gcc/tristate.h b/gcc/tristate.h
new file mode 100644
index 000000000000..88b96576f6a2
--- /dev/null
+++ b/gcc/tristate.h
@@ -0,0 +1,82 @@
+/* "True" vs "False" vs "Unknown".
+   Copyright (C) 2019 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/>.  */
+
+#ifndef GCC_ANALYZER_TRISTATE_H
+#define GCC_ANALYZER_TRISTATE_H
+
+/* "True" vs "False" vs "Unknown".  */
+
+class tristate {
+ public:
+  enum value {
+    TS_UNKNOWN,
+    TS_TRUE,
+    TS_FALSE
+  };
+
+  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;
+
+  bool is_known () const { return m_value != TS_UNKNOWN; }
+  bool is_true () const { return m_value == TS_TRUE; }
+  bool is_false () const { return m_value == TS_FALSE; }
+
+  tristate not_ () const;
+  tristate or_ (tristate other) const;
+  tristate and_ (tristate other) const;
+
+  bool operator== (const tristate &other) const
+  {
+    return m_value == other.m_value;
+  }
+
+  bool operator!= (const tristate &other) const
+  {
+    return m_value != other.m_value;
+  }
+
+ private:
+  enum value m_value;
+};
+
+/* Overloaded boolean operators on tristates.  */
+
+inline tristate
+operator ! (tristate t)
+{
+  return t.not_ ();
+}
+
+inline tristate
+operator || (tristate a, tristate b)
+{
+  return a.or_ (b);
+}
+
+inline tristate
+operator && (tristate a, tristate b)
+{
+  return a.and_ (b);
+}
+
+#endif /* GCC_ANALYZER_TRISTATE_H */
-- 
2.21.0

  parent reply	other threads:[~2019-12-13 18:12 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-13 18:12 [PATCH 00/45] v4 of analyzer patch kit David Malcolm
2019-12-13 18:11 ` [PATCH 04/45] analyzer: internal documentation David Malcolm
2019-12-13 18:11 ` [PATCH 09/45] Add diagnostic_metadata and CWE support David Malcolm
2019-12-13 18:11 ` [PATCH 02/45] hash-map-tests.c: add a selftest involving int_hash David Malcolm
2019-12-13 18:11 ` [PATCH 14/45] analyzer: add new files to Makefile.in David Malcolm
2019-12-13 18:11 ` [PATCH 05/45] Add pp_write_text_as_html_like_dot_to_stream David Malcolm
2019-12-16 17:32   ` David Malcolm
2019-12-13 18:12 ` [PATCH 10/45] Add diagnostic paths David Malcolm
2019-12-13 18:12 ` [PATCH 13/45] analyzer: changes to configure.ac David Malcolm
2019-12-13 18:12 ` [PATCH 06/45] sbitmap.h: add operator const sbitmap & to auto_sbitmap David Malcolm
2019-12-13 18:12 ` [PATCH 22/45] analyzer: new files: supergraph.{cc|h} David Malcolm
2019-12-13 18:12 ` [PATCH 27/45] analyzer: new files: pending-diagnostic.{cc|h} David Malcolm
2019-12-13 18:12 ` David Malcolm [this message]
2019-12-13 18:12 ` [PATCH 23/45] analyzer: new files: analyzer.{cc|h} David Malcolm
2019-12-13 18:12 ` [PATCH 39/45] analyzer: new file: exploded-graph.h David Malcolm
2019-12-13 18:12 ` [PATCH 08/45] Add -fdiagnostics-nn-line-numbers David Malcolm
2019-12-13 18:12 ` [PATCH 34/45] analyzer: new file: sm-taint.cc David Malcolm
2019-12-13 18:12 ` [PATCH 19/45] analyzer: new file: analyzer-pass.cc and pass registration David Malcolm
2019-12-13 18:12 ` [PATCH 20/45] analyzer: new files: graphviz.{cc|h} David Malcolm
2019-12-13 18:12 ` [PATCH 18/45] analyzer: logging support David Malcolm
2019-12-13 18:12 ` [PATCH 32/45] analyzer: new file: sm-sensitive.cc David Malcolm
2019-12-13 18:12 ` [PATCH 17/45] analyzer: command-line options David Malcolm
2019-12-13 18:12 ` [PATCH 15/45] analyzer: new files: analyzer-selftests.{cc|h} David Malcolm
2019-12-13 18:12 ` [PATCH 28/45] analyzer: new files: sm.{cc|h} David Malcolm
2019-12-13 18:12 ` [PATCH 37/45] analyzer: new files: program-point.{cc|h} David Malcolm
2019-12-13 18:12 ` [PATCH 12/45] timevar.def: add TVs for analyzer David Malcolm
2019-12-13 18:13 ` [PATCH 44/45] gdbinit.in: add break-on-saved-diagnostic David Malcolm
2019-12-13 18:14 ` [PATCH 41/45] analyzer: new files: engine.{cc|h} David Malcolm
2019-12-13 18:14 ` [PATCH 11/45] Add ordered_hash_map David Malcolm
2019-12-13 18:14 ` [PATCH 42/45] analyzer: new files: checker-path.{cc|h} David Malcolm
2019-12-13 18:15 ` [PATCH 25/45] analyzer: new files: constraint-manager.{cc|h} David Malcolm
2019-12-13 18:15 ` [PATCH 31/45] analyzer: new file: sm-pattern-test.cc David Malcolm
2019-12-13 18:15 ` [PATCH 30/45] analyzer: new file: sm-file.cc David Malcolm
2019-12-13 18:15 ` [PATCH 21/45] analyzer: new files: digraph.{cc|h} and shortest-paths.h David Malcolm
2019-12-13 18:15 ` [PATCH 45/45] analyzer: test suite David Malcolm
2019-12-13 18:16 ` [PATCH 16/45] analyzer: new builtins David Malcolm
2019-12-13 18:27   ` Jakub Jelinek
2019-12-13 18:32     ` David Malcolm
2019-12-18 14:45       ` [PATCH] analyzer: remove __analyzer builtins David Malcolm
2019-12-18 15:06         ` Jakub Jelinek
2019-12-13 18:16 ` [PATCH 38/45] analyzer: new files: program-state.{cc|h} David Malcolm
2019-12-13 18:16 ` [PATCH 01/45] gimple const-correctness fixes David Malcolm
2019-12-13 18:16 ` [PATCH 29/45] analyzer: new files: sm-malloc.cc and sm-malloc.dot David Malcolm
2019-12-13 18:16 ` [PATCH 40/45] analyzer: new files: state-purge.{cc|h} David Malcolm
2019-12-13 18:16 ` [PATCH 35/45] analyzer: new files: analysis-plan.{cc|h} David Malcolm
2019-12-13 18:16 ` [PATCH 36/45] analyzer: new files: call-string.{cc|h} David Malcolm
2019-12-13 18:16 ` [PATCH 26/45] analyzer: new files: region-model.{cc|h} David Malcolm
2019-12-13 18:16 ` [PATCH 03/45] analyzer: user-facing documentation David Malcolm
2019-12-13 18:16 ` [PATCH 33/45] analyzer: new file: sm-signal.cc David Malcolm
2019-12-13 18:16 ` [PATCH 43/45] analyzer: new files: diagnostic-manager.{cc|h} David Malcolm
2019-12-13 18:16 ` [PATCH 07/45] vec.h: add auto_delete_vec David Malcolm

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191213181134.1830-25-dmalcolm@redhat.com \
    --to=dmalcolm@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).