Currently the "make selftest" target run during each stage of the
build just runs the selftests within cc1.

As part of the fix for PR c++/81167 I want to be able to write
C++-specific selftests (to exercise the C++ implementation of
the pp's format_decoder).

Hence this patch generalizes the existing selftest logic in
Makefile.in so that selftests are run for both cc1 and cc1plus.
It also adds convenience methods for running them under
gdb and under valgrind.

It also reorganizes the existing lang-specific selftests, splitting
them into ones shared by c-family, and those that are specific
to individual members of the c family.  There aren't any of the
latter yet, but the followup adds some for C++.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu in
combination with the followup patch; the number of reported passes
from -fself-test for cc1 at each stage was unaffected by the kit:
  -fself-test: 39233 pass(es),
and cc1plus gained a similar line of output.

OK for trunk?

gcc/ChangeLog:
        * Makefile.in (SELFTEST_FLAGS): Drop "-x c", moving it to...
        (C_SELFTEST_FLAGS): New.
        (CPP_SELFTEST_FLAGS): New.
        (SELFTEST_DEPS): New, from deps of s-selftest.
        (C_SELFTEST_DEPS): New, from deps of s-selftest.
        (CPP_SELFTEST_DEPS): New.
        (selftest): Add dependency on s-selftest-c++.
        (s-selftest): Rename to...
        (s-selftest-c): ...this, moving deps to SELFTEST_DEPS
        and C_SELFTEST_DEPS, and using C_SELFTEST_FLAGS rather
        than SELFTEST_FLAGS.
        (selftest-gdb): Rename to...
        (selftest-c-gdb): ...this, using C_SELFTEST_DEPS and
        C_SELFTEST_FLAGS.
        (selftest-gdb): Reintroduce as an alias for selftest-c-gdb.
        (selftest-valgrind): Rename to...
        (selftest-c-valgrind): ...this, using C_SELFTEST_DEPS and
        C_SELFTEST_FLAGS.
        (selftest-valgrind): Reintroduce as an alias for
        selftest-c-valgrind.
        (s-selftest-c++): New.
        (selftest-c++-gdb): New.
        (selftest-c++-valgrind): New.

gcc/c-family/ChangeLog:
        * c-common.c (selftest::c_family_tests): New.
        * c-common.h (selftest::run_c_tests): Move decl to c/c-lang.h.
        (selftest::c_family_tests): New decl.

gcc/c/ChangeLog:
        * c-lang.c (selftest::run_c_tests): Move body to c_family_tests,
        and call that instead.
        * c-tree.h (selftest::run_c_tests): New decl.

gcc/cp/ChangeLog:
        * cp-lang.c (LANG_HOOKS_RUN_LANG_SELFTESTS): Define as
        selftest::run_cp_tests.
        (selftest::run_cp_tests): New function.
        * cp-tree.h (selftest::run_cp_tests): New decl.
---
 gcc/Makefile.in         | 62 +++++++++++++++++++++++++++++++++++++------------
 gcc/c-family/c-common.c | 16 +++++++++++++
 gcc/c-family/c-common.h |  6 ++++-
 gcc/c/c-lang.c          |  5 +++-
 gcc/c/c-tree.h          |  7 ++++++
 gcc/cp/cp-lang.c        | 24 +++++++++++++++++++
 gcc/cp/cp-tree.h        |  6 +++++
 7 files changed, 109 insertions(+), 17 deletions(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 67d69c1..23c1e03 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1903,30 +1903,62 @@ rest.cross: specs
 # "nul.s" on Windows. Because on Windows "nul" is a reserved file name.
 # Specify the path to gcc/testsuite/selftests within the srcdir
 # as an argument to -fself-test.
-SELFTEST_FLAGS = -nostdinc -x c /dev/null -S -o /dev/null \
+SELFTEST_FLAGS = -nostdinc /dev/null -S -o /dev/null \
        -fself-test=$(srcdir)/testsuite/selftests
 
-# Run the selftests during the build once we have a driver and a cc1,
+C_SELFTEST_FLAGS = -xc $(SELFTEST_FLAGS)
+CPP_SELFTEST_FLAGS = -xc++ $(SELFTEST_FLAGS)
+
+SELFTEST_DEPS = $(GCC_PASSES) stmp-int-hdrs $(srcdir)/testsuite/selftests
+
+C_SELFTEST_DEPS = cc1$(exeext) $(SELFTEST_DEPS)
+CPP_SELFTEST_DEPS = cc1plus$(exeext) $(SELFTEST_DEPS)
+
+# Run the selftests during the build once we have a driver and the frontend,
 # so that self-test failures are caught as early as possible.
-# Use "s-selftest" to ensure that we only run the selftests if the
-# driver, cc1, or selftest data change.
+# Use "s-selftest-FE" to ensure that we only run the selftests if the
+# driver, frontend, or selftest data change.
 .PHONY: selftest
-selftest: s-selftest
-s-selftest: $(GCC_PASSES) cc1$(exeext) stmp-int-hdrs \
-  $(srcdir)/testsuite/selftests
-       $(GCC_FOR_TARGET) $(SELFTEST_FLAGS)
+selftest: s-selftest-c s-selftest-c++
+
+# C selftests
+s-selftest-c: $(C_SELFTEST_DEPS)
+       $(GCC_FOR_TARGET) $(C_SELFTEST_FLAGS)
        $(STAMP) $@
 
-# Convenience method for running selftests under gdb:
-.PHONY: selftest-gdb
-selftest-gdb: $(GCC_PASSES) cc1$(exeext) stmp-int-hdrs
-       $(GCC_FOR_TARGET) $(SELFTEST_FLAGS) \
+# Convenience methods for running C selftests under gdb:
+.PHONY: selftest-c-gdb
+selftest-c-gdb: $(C_SELFTEST_DEPS)
+       $(GCC_FOR_TARGET) $(C_SELFTEST_FLAGS) \
          -wrapper gdb,--args
 
-# Convenience method for running selftests under valgrind:
+.PHONY: selftest-gdb
+selftest-gdb: selftest-c-gdb
+
+# Convenience methods for running C selftests under valgrind:
+.PHONY: selftest-c-valgrind
+selftest-c-valgrind: $(C_SELFTEST_DEPS)
+       $(GCC_FOR_TARGET) $(C_SELFTEST_FLAGS) \
+         -wrapper valgrind,--leak-check=full
+
 .PHONY: selftest-valgrind
-selftest-valgrind: $(GCC_PASSES) cc1$(exeext) stmp-int-hdrs
-       $(GCC_FOR_TARGET) $(SELFTEST_FLAGS) \
+selftest-valgrind: selftest-c-valgrind
+
+# C++ selftests
+s-selftest-c++: $(CPP_SELFTEST_DEPS)
+       $(GCC_FOR_TARGET) $(CPP_SELFTEST_FLAGS)
+       $(STAMP) $@
+
+# Convenience method for running C++ selftests under gdb:
+.PHONY: selftest-c++-gdb
+selftest-c++-gdb: $(CPP_SELFTEST_DEPS)
+       $(GCC_FOR_TARGET) $(CPP_SELFTEST_FLAGS) \
+         -wrapper gdb,--args
+
+# Convenience method for running C++ selftests under valgrind:
+.PHONY: selftest-c++-valgrind
+selftest-c++-valgrind: $(CPP_SELFTEST_DEPS)
+       $(GCC_FOR_TARGET) $(CPP_SELFTEST_FLAGS) \
          -wrapper valgrind,--leak-check=full
 
 # Recompile all the language-independent object files.
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 4395e51..8e68e6a 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -7996,4 +7996,20 @@ c_flt_eval_method (bool maybe_c11_only_p)
     return c_ts18661_flt_eval_method ();
 }
 
+#if CHECKING_P
+
+namespace selftest {
+
+/* Run all of the tests within c-family.  */
+
+void
+c_family_tests (void)
+{
+  c_format_c_tests ();
+}
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */
+
 #include "gt-c-family-c-common.h"
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 1748c19..21f71c3 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1556,8 +1556,12 @@ extern void add_no_sanitize_value (tree node, unsigned 
int flags);
 
 #if CHECKING_P
 namespace selftest {
+  /* Declarations for specific families of tests within c-family,
+     by source file, in alphabetical order.  */
   extern void c_format_c_tests (void);
-  extern void run_c_tests (void);
+
+  /* The entrypoint for running all of the above tests.  */
+  extern void c_family_tests (void);
 } // namespace selftest
 #endif /* #if CHECKING_P */
 
diff --git a/gcc/c/c-lang.c b/gcc/c/c-lang.c
index 510b7e7..e05741d 100644
--- a/gcc/c/c-lang.c
+++ b/gcc/c/c-lang.c
@@ -58,7 +58,10 @@ namespace selftest {
 void
 run_c_tests (void)
 {
-  c_format_c_tests ();
+  /* Run selftests shared within the C family.  */
+  c_family_tests ();
+
+  /* Additional C-specific tests.  */
 }
 
 } // namespace selftest
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index ce25fae..a8197eb 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -764,4 +764,11 @@ extern tree decl_constant_value_for_optimization (tree);
 
 extern vec<tree> incomplete_record_decls;
 
+#if CHECKING_P
+namespace selftest {
+  extern void run_c_tests (void);
+} // namespace selftest
+#endif /* #if CHECKING_P */
+
+
 #endif /* ! GCC_C_TREE_H */
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index defcbdc..805319a 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -79,6 +79,11 @@ static tree cxx_enum_underlying_base_type (const_tree);
 #undef LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE
 #define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE cxx_enum_underlying_base_type
 
+#if CHECKING_P
+#undef LANG_HOOKS_RUN_LANG_SELFTESTS
+#define LANG_HOOKS_RUN_LANG_SELFTESTS selftest::run_cp_tests
+#endif /* #if CHECKING_P */
+
 /* Each front end provides its own lang hook initializer.  */
 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 
@@ -229,6 +234,25 @@ tree cxx_enum_underlying_base_type (const_tree type)
   return underlying_type;
 }
 
+#if CHECKING_P
+
+namespace selftest {
+
+/* Implementation of LANG_HOOKS_RUN_LANG_SELFTESTS for the C++ frontend.  */
+
+void
+run_cp_tests (void)
+{
+  /* Run selftests shared within the C family.  */
+  c_family_tests ();
+
+  /* Additional C++-specific tests.  */
+}
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */
+
 
 #include "gt-cp-cp-lang.h"
 #include "gtype-cp.h"
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index e33bda6..126c24a 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7334,6 +7334,12 @@ extern tree cp_ubsan_maybe_instrument_downcast   
(location_t, tree, tree, tree);
 extern tree cp_ubsan_maybe_instrument_cast_to_vbase (location_t, tree, tree);
 extern void cp_ubsan_maybe_initialize_vtbl_ptrs (tree);
 
+#if CHECKING_P
+namespace selftest {
+  extern void run_cp_tests (void);
+} // namespace selftest
+#endif /* #if CHECKING_P */
+
 /* Inline bodies.  */
 
 inline tree
-- 
1.8.5.3

Reply via email to