This patch adds a way to only run a subset of the tests, by matching a regex against test names.
This can also be used to run just one test. gcc/ChangeLog: * common.opt (fself-test-regex=): New option. * selftest.c: Include diagnostic.h, xregex.h, options.h. (get_regerror): New function. (selftest::run_all_tests): Rename to... (selftest::run_tests): ...this, and add param REGEX_PATTERN, using it to filter the tests if non-NULL. * selftest.h (selftest::run_all_tests): Rename to... (selftest::run_tests): ...this, adding param REGEX_PATTERN. * toplev.c (toplev::run_self_tests): Update for above changes. --- 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 42e07e3..ada0b9b 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 (®ex, regex_pattern, 0); + if (errcode) + { + char *errmsg = get_regerror (errcode, ®ex); + 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 (®ex, 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 (®ex); + 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 ccb9c79..e240b98 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -2069,7 +2069,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