Jeff approved an early version of this: https://gcc.gnu.org/ml/gcc-patches/2015-10/msg03309.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 it to wide-int.cc and converts it to the new style. It's the only example so far of a type-parametrized test. gcc/ChangeLog: * selftest-run-tests.c (selftest::run_tests): Add call to wide_int_cc_tests. * selftest.h (wide_int_cc_tests): New declaration. * wide-int.cc: Include selftest.h and wide-int-print.h. (from_int <wide_int>): New function. (from_int <offset_int>): New function. (from_int <widest_int>): New function. (assert_deceq): New function. (assert_hexeq): New function. (test_printing <VALUE_TYPE>): New function template. (test_ops <VALUE_TYPE>): New function template. (test_comparisons <VALUE_TYPE>): New function template. (run_all_wide_int_tests <VALUE_TYPE>): New function template. (selftest::wide_int_cc_tests): New function. --- gcc/selftest-run-tests.c | 1 + gcc/selftest.h | 1 + gcc/wide-int.cc | 152 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+) diff --git a/gcc/selftest-run-tests.c b/gcc/selftest-run-tests.c index 4233351..ab334aa 100644 --- a/gcc/selftest-run-tests.c +++ b/gcc/selftest-run-tests.c @@ -46,6 +46,7 @@ selftest::run_tests () hash_map_tests_c_tests (); hash_set_tests_c_tests (); vec_c_tests (); + wide_int_cc_tests (); /* Mid-level data structures. */ input_c_tests (); diff --git a/gcc/selftest.h b/gcc/selftest.h index 2062a8b..a1d3074 100644 --- a/gcc/selftest.h +++ b/gcc/selftest.h @@ -55,6 +55,7 @@ extern void spellcheck_c_tests (); extern void tree_c_tests (); extern void tree_cfg_c_tests (); extern void vec_c_tests (); +extern void wide_int_cc_tests (); extern int num_passes; diff --git a/gcc/wide-int.cc b/gcc/wide-int.cc index 8648e7d..634dfb8 100644 --- a/gcc/wide-int.cc +++ b/gcc/wide-int.cc @@ -23,6 +23,8 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" +#include "selftest.h" +#include "wide-int-print.h" #define HOST_BITS_PER_HALF_WIDE_INT 32 @@ -2144,3 +2146,153 @@ template void generic_wide_int <wide_int_ref_storage <false> >::dump () const; template void generic_wide_int <wide_int_ref_storage <true> >::dump () const; template void offset_int::dump () const; template void widest_int::dump () const; + + +#if CHECKING_P + +/* Selftests for wide ints. We run these multiple times, once per type. */ + +/* Helper function for building a test value. */ + +template <class VALUE_TYPE> +static VALUE_TYPE +from_int (int i); + +/* Specializations of the fixture for each wide-int type. */ + +template <> +wide_int +from_int (int i) +{ + return wi::shwi (i, 32); +} + +template <> +offset_int +from_int (int i) +{ + return offset_int (i); +} + +template <> +widest_int +from_int (int i) +{ + return widest_int (i); +} + +/* Verify that print_dec (WI, ..., SGN) gives the expected string + representation (using base 10). */ + +static void +assert_deceq (const char *expected, const wide_int_ref &wi, signop sgn) +{ + char buf[WIDE_INT_PRINT_BUFFER_SIZE]; + print_dec (wi, buf, sgn); + ASSERT_STREQ (expected, buf); +} + +/* Likewise for base 16. */ + +static void +assert_hexeq (const char *expected, const wide_int_ref &wi) +{ + char buf[WIDE_INT_PRINT_BUFFER_SIZE]; + print_hex (wi, buf); + ASSERT_STREQ (expected, buf); +} + +/* Test cases. */ + +template <class VALUE_TYPE> +static void +test_printing () +{ + VALUE_TYPE a = from_int<VALUE_TYPE> (42); + assert_deceq ("42", a, SIGNED); + assert_hexeq ("0x2a", a); +} + +template <class VALUE_TYPE> +static void +test_ops () +{ + VALUE_TYPE a = from_int<VALUE_TYPE> (7); + VALUE_TYPE b = from_int<VALUE_TYPE> (3); + + /* Using functions. */ + assert_deceq ("-7", wi::neg (a), SIGNED); + assert_deceq ("10", wi::add (a, b), SIGNED); + assert_deceq ("4", wi::sub (a, b), SIGNED); + assert_deceq ("-4", wi::sub (b, a), SIGNED); + assert_deceq ("21", wi::mul (a, b), SIGNED); + + /* Using operators. */ + assert_deceq ("-7", -a, SIGNED); + assert_deceq ("10", a + b, SIGNED); + assert_deceq ("4", a - b, SIGNED); + assert_deceq ("-4", b - a, SIGNED); + assert_deceq ("21", a * b, SIGNED); +} + +template <class VALUE_TYPE> +static void +test_comparisons () +{ + VALUE_TYPE a = from_int<VALUE_TYPE> (7); + VALUE_TYPE b = from_int<VALUE_TYPE> (3); + + /* == */ + ASSERT_TRUE (wi::eq_p (a, a)); + ASSERT_FALSE (wi::eq_p (a, b)); + + /* != */ + ASSERT_TRUE (wi::ne_p (a, b)); + ASSERT_FALSE (wi::ne_p (a, a)); + + /* < */ + ASSERT_FALSE (wi::lts_p (a, a)); + ASSERT_FALSE (wi::lts_p (a, b)); + ASSERT_TRUE (wi::lts_p (b, a)); + + /* <= */ + ASSERT_TRUE (wi::les_p (a, a)); + ASSERT_FALSE (wi::les_p (a, b)); + ASSERT_TRUE (wi::les_p (b, a)); + + /* > */ + ASSERT_FALSE (wi::gts_p (a, a)); + ASSERT_TRUE (wi::gts_p (a, b)); + ASSERT_FALSE (wi::gts_p (b, a)); + + /* >= */ + ASSERT_TRUE (wi::ges_p (a, a)); + ASSERT_TRUE (wi::ges_p (a, b)); + ASSERT_FALSE (wi::ges_p (b, a)); + + /* comparison */ + ASSERT_EQ (-1, wi::cmps (b, a)); + ASSERT_EQ (0, wi::cmps (a, a)); + ASSERT_EQ (1, wi::cmps (a, b)); +} + +template <class VALUE_TYPE> +static void run_all_wide_int_tests () +{ + test_printing <VALUE_TYPE> (); + test_ops <VALUE_TYPE> (); + test_comparisons <VALUE_TYPE> (); +} + +namespace selftest { + +void +wide_int_cc_tests () +{ + run_all_wide_int_tests <wide_int> (); + run_all_wide_int_tests <offset_int> (); + run_all_wide_int_tests <widest_int> (); +} + +} // namespace selftest +#endif /* CHECKING_P */ -- 1.8.5.3