From 441dfc161d6caf50b269e6d129b17be517491b0e Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Mon, 23 May 2016 20:52:04 -0400
Subject: [PATCH 25/35] FIXME: add -fself-test-regex=

---
 gcc/common.opt |  4 ++++
 gcc/selftest.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
 gcc/selftest.h |  7 ++++---
 gcc/toplev.c   |  2 +-
 4 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/gcc/common.opt b/gcc/common.opt
index 95376bf..6aaf8e6 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2061,6 +2061,10 @@ fself-test
 Common Var(flag_self_test)
 Run self-tests.
 
+fself-test-regex=
+Common RejectNegative Joined Var(self_test_regex)
+Run self-tests matching the given regex.
+
 fsel-sched-pipelining
 Common Report Var(flag_sel_sched_pipelining) Init(0) Optimization
 Perform software pipelining of inner loops during selective scheduling.
diff --git a/gcc/selftest.c b/gcc/selftest.c
index 0197b3f..993a86e 100644
--- a/gcc/selftest.c
+++ b/gcc/selftest.c
@@ -21,12 +21,15 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "selftest.h"
+#include "diagnostic.h"
+#include "xregex.h"
+#include "options.h"
 
 #if CHECKING_P
 
 using namespace selftest;
 
-/* Helper function for ::selftest::run_all_tests.  */
+/* Helper function for ::selftest::run_tests.  */
 
 static int
 test_comparator (const void *p1, const void *p2)
@@ -36,11 +39,24 @@ test_comparator (const void *p1, const void *p2)
   return strcmp (t1->get_name (), t2->get_name ());
 }
 
-/* Locate and run all tests.
+/* Generate an error message describing a failed attempt to compile a
+   regex.  The return value should be freed.  */
+
+static char *
+get_regerror (int errcode, regex_t *compiled)
+{
+  size_t length = regerror (errcode, compiled, NULL, 0);
+  char *buffer = (char *)xmalloc (length);
+  (void) regerror (errcode, compiled, buffer, length);
+  return buffer;
+}
+
+/* Locate and run tests.  If REGEX_PATTERN is NULL, all tests are run.
+   Otherwise, only tests with names matching the regex are run.
    Return the number of failures that occurred.  */
 
 int
-selftest::run_all_tests ()
+selftest::run_tests (const char *regex_pattern)
 {
   /* Create all the tests, in an arbitrary order (based on
      the order of construction of the global "registrator" instances).  */
@@ -57,11 +73,31 @@ selftest::run_all_tests ()
   /* Sort the tests into a predictable order.  */
   tests.qsort (test_comparator);
 
+  regex_t regex;
+  if (regex_pattern)
+    {
+      int errcode = regcomp (&regex, regex_pattern, 0);
+      if (errcode)
+	{
+	  char *errmsg = get_regerror (errcode, &regex);
+	  error ("error compiling regex pattern %qs: %s", regex_pattern, errmsg);
+	  free (errmsg);
+	  return 1;
+	}
+    }
+
   /* Run all the tests, in order.  */
   unsigned i;
   test *t;
   FOR_EACH_VEC_ELT (tests, i, t)
     {
+      if (regex_pattern)
+	{
+	  int err = regexec (&regex, t->get_name (), 0, NULL, 0);
+	  if (err)
+	    /* Test did not match.  */
+	    continue;
+	}
       r.begin_test (t);
       t->run ();
       r.end_test (t);
@@ -71,6 +107,9 @@ selftest::run_all_tests ()
   FOR_EACH_VEC_ELT (tests, i, t)
     delete t;
 
+  if (regex_pattern)
+    regfree (&regex);
+
   return r.get_num_failures ();
 }
 
diff --git a/gcc/selftest.h b/gcc/selftest.h
index 95262ce..aa0232a 100644
--- a/gcc/selftest.h
+++ b/gcc/selftest.h
@@ -31,9 +31,10 @@ class test;
 class runner;
 class registrator;
 
-/* The entrypoint for running all tests.  */
+/* The entrypoint for running all tests, or all tests matching
+   REGEX_PATTERN.  */
 
-extern int run_all_tests ();
+extern int run_tests (const char *regex_pattern);
 
 /* The class ::selftest::runner is responsible for gathering results,
    and for output.  */
@@ -93,7 +94,7 @@ class test
    Global instances are created via the REGISTER_TEST below.
    The constructor runs before main, wiring them up into a
    singly-linked list, which can be traversed by
-   ::selftest::run_all_tests.  */
+   ::selftest::run_tests.  */
 
 class registrator
 {
diff --git a/gcc/toplev.c b/gcc/toplev.c
index bb5ac5d..e903761 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -2067,7 +2067,7 @@ toplev::run_self_tests ()
   bitmap_obstack_initialize (NULL);
 
   /* Run the tests.  */
-  int result = ::selftest::run_all_tests ();
+  int result = ::selftest::run_tests (self_test_regex);
 
   /* Ensure that a test failure leads to the process exiting with
      a non-zero exit code.  */
-- 
1.8.5.3

