From 4c2e6040416cbf8a761a0eab67a029e2579f24df Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 10 Jun 2015 06:07:15 -0400
Subject: [PATCH 09/16] gimple.c: add selftests

Jeff approved an earlier version of this (as
unittests/test-gimple.c):
https://gcc.gnu.org/ml/gcc-patches/2015-10/msg03304.html

> OK if/when prereqs are approved. Minor twiddling if we end
> up moving it elsewhere or standardizing/reducing header files
> is pre-approved.

This version moves the tests into gimple.c and updates them to
the new style.

gcc/ChangeLog:
	* gimple.c: Include "selftest.h".
	Include "gimple-pretty-print.h".
	(verify_gimple_pp): New function.
	(test_assign_single): New function.
	(test_assign_binop): New function.
	(test_nop_stmt): New function.
	(test_return_stmt): New function.
	(test_return_without_value): New function.
	(selftest::gimple_c_tests): New function.
---
 gcc/gimple.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/gcc/gimple.c b/gcc/gimple.c
index d822fab..c0a11a9 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -38,6 +38,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-walk.h"
 #include "gimplify.h"
 #include "target.h"
+#include "selftest.h"
+#include "gimple-pretty-print.h"
 
 
 /* All the tuples have their operand vector (if present) at the very bottom
@@ -3016,3 +3018,120 @@ maybe_remove_unused_call_args (struct function *fn, gimple *stmt)
       update_stmt_fn (fn, stmt);
     }
 }
+
+#if CHECKING_P
+
+/* Selftests for core gimple structures.  */
+
+/* Helper function for selftests.  */
+
+static void
+verify_gimple_pp (const char *expected, gimple *stmt)
+{
+  pretty_printer pp;
+  pp_gimple_stmt_1 (&pp, stmt, 0 /* spc */, 0 /* flags */);
+  ASSERT_STREQ (expected, pp_formatted_text (&pp));
+}
+
+static void
+test_assign_single ()
+{
+  /* Build "tmp = 5;"  */
+  tree type = integer_type_node;
+  tree lhs = build_decl (UNKNOWN_LOCATION, VAR_DECL,
+			 get_identifier ("tmp"),
+			 type);
+  tree rhs = build_int_cst (type, 5);
+  gassign *stmt = gimple_build_assign (lhs, rhs);
+  verify_gimple_pp ("tmp = 5;", stmt);
+
+  ASSERT_TRUE (is_gimple_assign (stmt));
+  ASSERT_EQ (lhs, gimple_assign_lhs (stmt));
+  ASSERT_EQ (lhs, gimple_get_lhs (stmt));
+  ASSERT_EQ (rhs, gimple_assign_rhs1 (stmt));
+  ASSERT_EQ (NULL, gimple_assign_rhs2 (stmt));
+  ASSERT_EQ (NULL, gimple_assign_rhs3 (stmt));
+  ASSERT_TRUE (gimple_assign_single_p (stmt));
+  ASSERT_EQ (INTEGER_CST, gimple_assign_rhs_code (stmt));
+}
+
+static void
+test_assign_binop ()
+{
+  /* Build "tmp = a * b;"  */
+  tree type = integer_type_node;
+  tree lhs = build_decl (UNKNOWN_LOCATION, VAR_DECL,
+			 get_identifier ("tmp"),
+			 type);
+  tree a = build_decl (UNKNOWN_LOCATION, VAR_DECL,
+		       get_identifier ("a"),
+		       type);
+  tree b = build_decl (UNKNOWN_LOCATION, VAR_DECL,
+		       get_identifier ("b"),
+		       type);
+  gassign *stmt = gimple_build_assign (lhs, MULT_EXPR, a, b);
+  verify_gimple_pp ("tmp = a * b;", stmt);
+
+  ASSERT_TRUE (is_gimple_assign (stmt));
+  ASSERT_EQ (lhs, gimple_assign_lhs (stmt));
+  ASSERT_EQ (lhs, gimple_get_lhs (stmt));
+  ASSERT_EQ (a, gimple_assign_rhs1 (stmt));
+  ASSERT_EQ (b, gimple_assign_rhs2 (stmt));
+  ASSERT_EQ (NULL, gimple_assign_rhs3 (stmt));
+  ASSERT_FALSE (gimple_assign_single_p (stmt));
+  ASSERT_EQ (MULT_EXPR, gimple_assign_rhs_code (stmt));
+}
+
+static void
+test_nop_stmt ()
+{
+  gimple *stmt = gimple_build_nop ();
+  verify_gimple_pp ("GIMPLE_NOP", stmt);
+  ASSERT_EQ (GIMPLE_NOP, gimple_code (stmt));
+  ASSERT_EQ (NULL, gimple_get_lhs (stmt));
+  ASSERT_FALSE (gimple_assign_single_p (stmt));
+}
+
+static void
+test_return_stmt ()
+{
+  /* Build "return 7;"  */
+  tree type = integer_type_node;
+  tree val = build_int_cst (type, 7);
+  greturn *stmt = gimple_build_return (val);
+  verify_gimple_pp ("return 7;", stmt);
+
+  ASSERT_EQ (GIMPLE_RETURN, gimple_code (stmt));
+  ASSERT_EQ (NULL, gimple_get_lhs (stmt));
+  ASSERT_EQ (val, gimple_return_retval (stmt));
+  ASSERT_FALSE (gimple_assign_single_p (stmt));
+}
+
+static void
+test_return_without_value ()
+{
+  greturn *stmt = gimple_build_return (NULL);
+  verify_gimple_pp ("return;", stmt);
+
+  ASSERT_EQ (GIMPLE_RETURN, gimple_code (stmt));
+  ASSERT_EQ (NULL, gimple_get_lhs (stmt));
+  ASSERT_EQ (NULL, gimple_return_retval (stmt));
+  ASSERT_FALSE (gimple_assign_single_p (stmt));
+}
+
+namespace selftest {
+
+void
+gimple_c_tests ()
+{
+  test_assign_single ();
+  test_assign_binop ();
+  test_nop_stmt ();
+  test_return_stmt ();
+  test_return_without_value ();
+}
+
+} // namespace selftest
+
+
+#endif /* CHECKING_P */
-- 
1.8.5.3

