From b29d260629e8dbf810d3a2b7afcbd7afabab88e0 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Mon, 31 Aug 2015 21:13:52 -0400
Subject: [PATCH 40/56] FIXME: Add the WIP C frontend gimple-range unittesting
 plugin (without the plugin.exp change)

---
 ...iagnostic_plugin_test_gimple_expression_range.c | 165 +++++++++++++++++++++
 1 file changed, 165 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_gimple_expression_range.c

diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_gimple_expression_range.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_gimple_expression_range.c
new file mode 100644
index 0000000..0b4e41b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_gimple_expression_range.c
@@ -0,0 +1,165 @@
+/* This plugin verifies the source-code location ranges of
+   expressions, after gimplification.  */
+#error not written yet
+/* { dg-options "-O" } */
+
+#include "gcc-plugin.h"
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "toplev.h"
+#include "basic-block.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "tree.h"
+#include "tree-pass.h"
+#include "intl.h"
+#include "plugin-version.h"
+#include "diagnostic.h"
+#include "context.h"
+#include "gcc-rich-location.h"
+#include "print-tree.h"
+
+int plugin_is_GPL_compatible;
+
+const pass_data pass_data_test_gimple_expression_range =
+{
+  GIMPLE_PASS, /* type */
+  "test_gimple_expression_range", /* name */
+  OPTGROUP_NONE, /* optinfo_flags */
+  TV_NONE, /* tv_id */
+  PROP_ssa, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  0, /* todo_flags_finish */
+};
+
+class pass_test_gimple_expression_range : public gimple_opt_pass
+{
+public:
+  pass_test_gimple_expression_range(gcc::context *ctxt)
+    : gimple_opt_pass(pass_data_test_gimple_expression_range, ctxt)
+  {}
+
+  /* opt_pass methods: */
+  bool gate (function *) { return true; }
+  virtual unsigned int execute (function *);
+
+}; // class pass_test_gimple_expression_range
+
+/* FIXME.  */
+
+static gcall *
+check_for_named_call (gimple stmt,
+		      const char *funcname, unsigned int num_args)
+{
+  gcc_assert (funcname);
+
+  gcall *call = dyn_cast <gcall *> (stmt);
+  if (!call)
+    return NULL;
+
+  tree fndecl = gimple_call_fndecl (call);
+  if (!fndecl)
+    return NULL;
+
+  if (strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), funcname))
+    return NULL;
+
+  if (gimple_call_num_args (call) != num_args)
+    {
+      error_at (stmt->location, "expected number of args: %i (got %i)",
+		num_args, gimple_call_num_args (call));
+      return NULL;
+    }
+
+  return call;
+}
+
+static void
+emit_warning (rich_location *richloc)
+{
+  location_range *range = richloc->get_range (0);
+  warning_at_rich_loc (richloc, 0,
+		       "range %i:%i-%i:%i",
+		       range->m_start.line,
+		       range->m_start.column,
+		       range->m_finish.line,
+		       range->m_finish.column);
+}
+
+/* Support code for verifying that we are correctly tracking ranges
+   for expressions, for use by diagnostic-test-expressions-*.c.  */
+
+static void
+test_expressions (gimple stmt)
+{
+  gcall *call = check_for_named_call (stmt, "__emit_expression_range", 2);
+  if (!call)
+    return;
+
+  tree expr = gimple_call_arg (call, 1);
+
+  gcc_rich_location richloc (stmt->location);
+  richloc.add_expr (expr);
+
+  emit_warning (&richloc);
+}
+
+unsigned int
+pass_test_gimple_expression_range::execute (function *fun)
+{
+  gimple_stmt_iterator gsi;
+  basic_block bb;
+
+  FOR_EACH_BB_FN (bb, fun)
+    for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+      {
+	gimple stmt = gsi_stmt (gsi);
+	test_expressions (stmt);
+      }
+
+  return 0;
+}
+
+static gimple_opt_pass *
+make_pass_test_gimple_expression_range (gcc::context *ctxt)
+{
+  return new pass_test_gimple_expression_range (ctxt);
+}
+
+int
+plugin_init (struct plugin_name_args *plugin_info,
+	     struct plugin_gcc_version *version)
+{
+  struct register_pass_info pass_info;
+  const char *plugin_name = plugin_info->base_name;
+  int argc = plugin_info->argc;
+  struct plugin_argument *argv = plugin_info->argv;
+
+  if (!plugin_default_version_check (version, &gcc_version))
+    return 1;
+
+  pass_info.pass = make_pass_test_gimple_expression_range (g);
+  pass_info.reference_pass_name = "ssa";
+  pass_info.ref_pass_instance_number = 1;
+  pass_info.pos_op = PASS_POS_INSERT_AFTER;
+  register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
+		     &pass_info);
+
+  return 0;
+}
-- 
1.8.5.3

