|  | /* Self tests of the gmp-utils API. | 
|  |  | 
|  | Copyright (C) 2019-2024 Free Software Foundation, Inc. | 
|  |  | 
|  | This file is part of GDB. | 
|  |  | 
|  | This program is free software; you can redistribute it and/or modify | 
|  | it under the terms of the GNU General Public License as published by | 
|  | the Free Software Foundation; either version 3 of the License, or | 
|  | (at your option) any later version. | 
|  |  | 
|  | This program is distributed in the hope that it will be useful, | 
|  | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | GNU General Public License for more details. | 
|  |  | 
|  | You should have received a copy of the GNU General Public License | 
|  | along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ | 
|  |  | 
|  | #include "gmp-utils.h" | 
|  | #include "gdbsupport/selftest.h" | 
|  | #include "extract-store-integer.h" | 
|  |  | 
|  | #include <math.h> | 
|  |  | 
|  | namespace selftests { | 
|  |  | 
|  | /* Perform a series of general tests of gdb_mpz's as_integer method. | 
|  |  | 
|  | This function limits itself to values which are in range (out-of-range | 
|  | values will be tested separately).  In doing so, it tries to be reasonably | 
|  | exhaustive, by testing the edges, as well as a reasonable set of values | 
|  | including negative ones, zero, and positive values.  */ | 
|  |  | 
|  | static void | 
|  | gdb_mpz_as_integer () | 
|  | { | 
|  | /* Test a range of values, both as LONGEST and ULONGEST.  */ | 
|  | gdb_mpz v; | 
|  | LONGEST l_expected; | 
|  | ULONGEST ul_expected; | 
|  |  | 
|  | /* Start with the smallest LONGEST  */ | 
|  | l_expected = (LONGEST) 1 << (sizeof (LONGEST) * 8 - 1); | 
|  |  | 
|  | v = gdb_mpz::pow (2, sizeof (LONGEST) * 8 - 1); | 
|  | v.negate (); | 
|  |  | 
|  | SELF_CHECK (v.as_integer<LONGEST> () == l_expected); | 
|  |  | 
|  | /* Try with a small range of integers including negative, zero, | 
|  | and positive values.  */ | 
|  | for (int i = -256; i <= 256; i++) | 
|  | { | 
|  | l_expected = (LONGEST) i; | 
|  | v = i; | 
|  | SELF_CHECK (v.as_integer<LONGEST> () == l_expected); | 
|  |  | 
|  | if (i >= 0) | 
|  | { | 
|  | ul_expected = (ULONGEST) i; | 
|  | v = ul_expected; | 
|  | SELF_CHECK (v.as_integer<ULONGEST> () == ul_expected); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Try with LONGEST_MAX.  */ | 
|  | l_expected = LONGEST_MAX; | 
|  | ul_expected = (ULONGEST) l_expected; | 
|  |  | 
|  | v = gdb_mpz::pow (2, sizeof (LONGEST) * 8 - 1); | 
|  | v -= 1; | 
|  |  | 
|  | SELF_CHECK (v.as_integer<LONGEST> () == l_expected); | 
|  | SELF_CHECK (v.as_integer<ULONGEST> () == ul_expected); | 
|  |  | 
|  | /* Try with ULONGEST_MAX.  */ | 
|  | ul_expected = ULONGEST_MAX; | 
|  | v = gdb_mpz::pow (2, sizeof (LONGEST) * 8); | 
|  | v -= 1; | 
|  |  | 
|  | SELF_CHECK (v.as_integer<ULONGEST> () == ul_expected); | 
|  | } | 
|  |  | 
|  | /* A helper function which calls the given gdb_mpz object's as_integer | 
|  | method with the given type T, and verifies that this triggers | 
|  | an error due to VAL's value being out of range for type T.  */ | 
|  |  | 
|  | template<typename T, typename = gdb::Requires<std::is_integral<T>>> | 
|  | static void | 
|  | check_as_integer_raises_out_of_range_error (const gdb_mpz &val) | 
|  | { | 
|  | try | 
|  | { | 
|  | val.as_integer<T> (); | 
|  | } | 
|  | catch (const gdb_exception_error &ex) | 
|  | { | 
|  | SELF_CHECK (ex.reason == RETURN_ERROR); | 
|  | SELF_CHECK (ex.error == GENERIC_ERROR); | 
|  | SELF_CHECK (strstr (ex.what (), "Cannot export value") != nullptr); | 
|  | return; | 
|  | } | 
|  | /* The expected exception did not get raised.  */ | 
|  | SELF_CHECK (false); | 
|  | } | 
|  |  | 
|  | /* Perform out-of-range tests of gdb_mpz's as_integer method. | 
|  |  | 
|  | The goal of this function is to verify that gdb_mpz::as_integer | 
|  | handles out-of-range values correctly.  */ | 
|  |  | 
|  | static void | 
|  | gdb_mpz_as_integer_out_of_range () | 
|  | { | 
|  | gdb_mpz v; | 
|  |  | 
|  | /* Try LONGEST_MIN minus 1.  */ | 
|  | v = gdb_mpz::pow (2, sizeof (LONGEST) * 8 - 1); | 
|  | v.negate (); | 
|  | v -= 1; | 
|  |  | 
|  | check_as_integer_raises_out_of_range_error<ULONGEST> (v); | 
|  | check_as_integer_raises_out_of_range_error<LONGEST> (v); | 
|  |  | 
|  | /* Try negative one (-1). */ | 
|  | v = -1; | 
|  |  | 
|  | check_as_integer_raises_out_of_range_error<ULONGEST> (v); | 
|  | SELF_CHECK (v.as_integer<LONGEST> () == (LONGEST) -1); | 
|  |  | 
|  | /* Try LONGEST_MAX plus 1.  */ | 
|  | v = LONGEST_MAX; | 
|  | v += 1; | 
|  |  | 
|  | SELF_CHECK (v.as_integer<ULONGEST> () == (ULONGEST) LONGEST_MAX + 1); | 
|  | check_as_integer_raises_out_of_range_error<LONGEST> (v); | 
|  |  | 
|  | /* Try ULONGEST_MAX plus 1.  */ | 
|  | v = ULONGEST_MAX; | 
|  | v += 1; | 
|  |  | 
|  | check_as_integer_raises_out_of_range_error<ULONGEST> (v); | 
|  | check_as_integer_raises_out_of_range_error<LONGEST> (v); | 
|  | } | 
|  |  | 
|  | /* A helper function to store the given integer value into a buffer, | 
|  | before reading it back into a gdb_mpz.  Sets ACTUAL to the value | 
|  | read back, while at the same time setting EXPECTED as the value | 
|  | we would expect to be read back. | 
|  |  | 
|  | Note that this function does not perform the comparison between | 
|  | EXPECTED and ACTUAL.  The caller will do it inside a SELF_CHECK | 
|  | call, allowing the line information shown when the test fails | 
|  | to provide a bit more information about the kind of values | 
|  | that were used when the check failed.  This makes the writing | 
|  | of the tests a little more verbose, but the debugging in case | 
|  | of problems should hopefuly be easier.  */ | 
|  |  | 
|  | template<typename T> | 
|  | void | 
|  | store_and_read_back (T val, size_t buf_len, enum bfd_endian byte_order, | 
|  | gdb_mpz &expected, gdb_mpz &actual) | 
|  | { | 
|  | gdb_byte *buf; | 
|  |  | 
|  | expected = val; | 
|  |  | 
|  | buf = (gdb_byte *) alloca (buf_len); | 
|  | store_integer (buf, buf_len, byte_order, val); | 
|  |  | 
|  | /* Pre-initialize ACTUAL to something that's not the expected value.  */ | 
|  | actual = expected; | 
|  | actual -= 500; | 
|  |  | 
|  | actual.read ({buf, buf_len}, byte_order, !std::is_signed<T>::value); | 
|  | } | 
|  |  | 
|  | /* Test the gdb_mpz::read method over a reasonable range of values. | 
|  |  | 
|  | The testing is done by picking an arbitrary buffer length, after | 
|  | which we test every possible value that this buffer allows, both | 
|  | with signed numbers as well as unsigned ones.  */ | 
|  |  | 
|  | static void | 
|  | gdb_mpz_read_all_from_small () | 
|  | { | 
|  | /* Start with a type whose size is small enough that we can afford | 
|  | to check the complete range.  */ | 
|  |  | 
|  | int buf_len = 1; | 
|  | LONGEST l_min = -pow (2.0, buf_len * 8 - 1); | 
|  | LONGEST l_max = pow (2.0, buf_len * 8 - 1) - 1; | 
|  |  | 
|  | for (LONGEST l = l_min; l <= l_max; l++) | 
|  | { | 
|  | gdb_mpz expected, actual; | 
|  |  | 
|  | store_and_read_back (l, buf_len, BFD_ENDIAN_BIG, expected, actual); | 
|  | SELF_CHECK (actual ==  expected); | 
|  |  | 
|  | store_and_read_back (l, buf_len, BFD_ENDIAN_LITTLE, expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  | } | 
|  |  | 
|  | /* Do the same as above, but with an unsigned type.  */ | 
|  | ULONGEST ul_min = 0; | 
|  | ULONGEST ul_max = pow (2.0, buf_len * 8) - 1; | 
|  |  | 
|  | for (ULONGEST ul = ul_min; ul <= ul_max; ul++) | 
|  | { | 
|  | gdb_mpz expected, actual; | 
|  |  | 
|  | store_and_read_back (ul, buf_len, BFD_ENDIAN_BIG, expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  |  | 
|  | store_and_read_back (ul, buf_len, BFD_ENDIAN_LITTLE, expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Test the gdb_mpz::read the extremes of LONGEST and ULONGEST.  */ | 
|  |  | 
|  | static void | 
|  | gdb_mpz_read_min_max () | 
|  | { | 
|  | gdb_mpz expected, actual; | 
|  |  | 
|  | /* Start with the smallest LONGEST.  */ | 
|  |  | 
|  | LONGEST l_min = (LONGEST) 1 << (sizeof (LONGEST) * 8 - 1); | 
|  |  | 
|  | store_and_read_back (l_min, sizeof (LONGEST), BFD_ENDIAN_BIG, | 
|  | expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  |  | 
|  | store_and_read_back (l_min, sizeof (LONGEST), BFD_ENDIAN_LITTLE, | 
|  | expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  |  | 
|  | /* Same with LONGEST_MAX.  */ | 
|  |  | 
|  | LONGEST l_max = LONGEST_MAX; | 
|  |  | 
|  | store_and_read_back (l_max, sizeof (LONGEST), BFD_ENDIAN_BIG, | 
|  | expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  |  | 
|  | store_and_read_back (l_max, sizeof (LONGEST), BFD_ENDIAN_LITTLE, | 
|  | expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  |  | 
|  | /* Same with the smallest ULONGEST.  */ | 
|  |  | 
|  | ULONGEST ul_min = 0; | 
|  |  | 
|  | store_and_read_back (ul_min, sizeof (ULONGEST), BFD_ENDIAN_BIG, | 
|  | expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  |  | 
|  | store_and_read_back (ul_min, sizeof (ULONGEST), BFD_ENDIAN_LITTLE, | 
|  | expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  |  | 
|  | /* Same with ULONGEST_MAX.  */ | 
|  |  | 
|  | ULONGEST ul_max = ULONGEST_MAX; | 
|  |  | 
|  | store_and_read_back (ul_max, sizeof (ULONGEST), BFD_ENDIAN_BIG, | 
|  | expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  |  | 
|  | store_and_read_back (ul_max, sizeof (ULONGEST), BFD_ENDIAN_LITTLE, | 
|  | expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  | } | 
|  |  | 
|  | /* A helper function which creates a gdb_mpz object from the given | 
|  | integer VAL, and then writes it using its gdb_mpz::write method. | 
|  |  | 
|  | The written value is then extracted from the buffer and returned, | 
|  | for comparison with the original. | 
|  |  | 
|  | Note that this function does not perform the comparison between | 
|  | VAL and the returned value.  The caller will do it inside a SELF_CHECK | 
|  | call, allowing the line information shown when the test fails | 
|  | to provide a bit more information about the kind of values | 
|  | that were used when the check failed.  This makes the writing | 
|  | of the tests a little more verbose, but the debugging in case | 
|  | of problems should hopefuly be easier.  */ | 
|  |  | 
|  | template<typename T> | 
|  | T | 
|  | write_and_extract (T val, size_t buf_len, enum bfd_endian byte_order) | 
|  | { | 
|  | gdb_mpz v (val); | 
|  |  | 
|  | SELF_CHECK (v.as_integer<T> () == val); | 
|  |  | 
|  | gdb_byte *buf = (gdb_byte *) alloca (buf_len); | 
|  | v.write ({buf, buf_len}, byte_order, !std::is_signed<T>::value); | 
|  |  | 
|  | return extract_integer<T> ({buf, buf_len}, byte_order); | 
|  | } | 
|  |  | 
|  | /* Test the gdb_mpz::write method over a reasonable range of values. | 
|  |  | 
|  | The testing is done by picking an arbitrary buffer length, after | 
|  | which we test every possible value that this buffer allows.  */ | 
|  |  | 
|  | static void | 
|  | gdb_mpz_write_all_from_small () | 
|  | { | 
|  | int buf_len = 1; | 
|  | LONGEST l_min = -pow (2.0, buf_len * 8 - 1); | 
|  | LONGEST l_max = pow (2.0, buf_len * 8 - 1) - 1; | 
|  |  | 
|  | for (LONGEST l = l_min; l <= l_max; l++) | 
|  | { | 
|  | SELF_CHECK (write_and_extract (l, buf_len, BFD_ENDIAN_BIG) == l); | 
|  | SELF_CHECK (write_and_extract (l, buf_len, BFD_ENDIAN_LITTLE) == l); | 
|  | } | 
|  |  | 
|  | /* Do the same as above, but with an unsigned type.  */ | 
|  | ULONGEST ul_min = 0; | 
|  | ULONGEST ul_max = pow (2.0, buf_len * 8) - 1; | 
|  |  | 
|  | for (ULONGEST ul = ul_min; ul <= ul_max; ul++) | 
|  | { | 
|  | SELF_CHECK (write_and_extract (ul, buf_len, BFD_ENDIAN_BIG) == ul); | 
|  | SELF_CHECK (write_and_extract (ul, buf_len, BFD_ENDIAN_LITTLE) == ul); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* Test the gdb_mpz::write the extremes of LONGEST and ULONGEST.  */ | 
|  |  | 
|  | static void | 
|  | gdb_mpz_write_min_max () | 
|  | { | 
|  | /* Start with the smallest LONGEST.  */ | 
|  |  | 
|  | LONGEST l_min = (LONGEST) 1 << (sizeof (LONGEST) * 8 - 1); | 
|  | SELF_CHECK (write_and_extract (l_min, sizeof (LONGEST), BFD_ENDIAN_BIG) | 
|  | == l_min); | 
|  | SELF_CHECK (write_and_extract (l_min, sizeof (LONGEST), BFD_ENDIAN_LITTLE) | 
|  | == l_min); | 
|  |  | 
|  | /* Same with LONGEST_MAX.  */ | 
|  |  | 
|  | LONGEST l_max = LONGEST_MAX; | 
|  | SELF_CHECK (write_and_extract (l_max, sizeof (LONGEST), BFD_ENDIAN_BIG) | 
|  | == l_max); | 
|  | SELF_CHECK (write_and_extract (l_max, sizeof (LONGEST), BFD_ENDIAN_LITTLE) | 
|  | == l_max); | 
|  |  | 
|  | /* Same with the smallest ULONGEST.  */ | 
|  |  | 
|  | ULONGEST ul_min = (ULONGEST) 1 << (sizeof (ULONGEST) * 8 - 1); | 
|  | SELF_CHECK (write_and_extract (ul_min, sizeof (ULONGEST), BFD_ENDIAN_BIG) | 
|  | == ul_min); | 
|  | SELF_CHECK (write_and_extract (ul_min, sizeof (ULONGEST), BFD_ENDIAN_LITTLE) | 
|  | == ul_min); | 
|  |  | 
|  | /* Same with ULONGEST_MAX.  */ | 
|  |  | 
|  | ULONGEST ul_max = ULONGEST_MAX; | 
|  | SELF_CHECK (write_and_extract (ul_max, sizeof (ULONGEST), BFD_ENDIAN_BIG) | 
|  | == ul_max); | 
|  | SELF_CHECK (write_and_extract (ul_max, sizeof (ULONGEST), BFD_ENDIAN_LITTLE) | 
|  | == ul_max); | 
|  | } | 
|  |  | 
|  | /* A helper function which stores the signed number, the unscaled value | 
|  | of a fixed point object, into a buffer, and then uses gdb_mpq's | 
|  | read_fixed_point to read it as a fixed_point value, with | 
|  | the given parameters. | 
|  |  | 
|  | EXPECTED is set to the value we expected to get after the call | 
|  | to read_fixed_point.  ACTUAL is the value we actually do get. | 
|  |  | 
|  | Note that this function does not perform the comparison between | 
|  | EXPECTED and ACTUAL.  The caller will do it inside a SELF_CHECK | 
|  | call, allowing the line information shown when the test fails | 
|  | to provide a bit more information about the kind of values | 
|  | that were used when the check failed.  This makes the writing | 
|  | of the tests a little more verbose, but the debugging in case | 
|  | of problems should hopefuly be easier.  */ | 
|  |  | 
|  | static void | 
|  | read_fp_test (int unscaled, const gdb_mpq &scaling_factor, | 
|  | enum bfd_endian byte_order, | 
|  | gdb_mpq &expected, gdb_mpq &actual) | 
|  | { | 
|  | /* For this kind of testing, we'll use a buffer the same size as | 
|  | our unscaled parameter.  */ | 
|  | const size_t len = sizeof (unscaled); | 
|  | gdb_byte buf[len]; | 
|  | store_signed_integer (buf, len, byte_order, unscaled); | 
|  |  | 
|  | actual.read_fixed_point ({buf, len}, byte_order, 0, scaling_factor); | 
|  |  | 
|  | expected = gdb_mpq (unscaled, 1); | 
|  | expected *= scaling_factor; | 
|  | } | 
|  |  | 
|  | /* Perform various tests of the gdb_mpq::read_fixed_point method.  */ | 
|  |  | 
|  | static void | 
|  | gdb_mpq_read_fixed_point () | 
|  | { | 
|  | gdb_mpq expected, actual; | 
|  |  | 
|  | /* Pick an arbitrary scaling_factor; this operation is trivial enough | 
|  | thanks to GMP that the value we use isn't really important.  */ | 
|  | gdb_mpq scaling_factor (3, 5); | 
|  |  | 
|  | /* Try a few values, both negative and positive... */ | 
|  |  | 
|  | read_fp_test (-256, scaling_factor, BFD_ENDIAN_BIG, expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  | read_fp_test (-256, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  |  | 
|  | read_fp_test (-1, scaling_factor, BFD_ENDIAN_BIG, expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  | read_fp_test (-1, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  |  | 
|  | read_fp_test (0, scaling_factor, BFD_ENDIAN_BIG, expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  | read_fp_test (0, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  |  | 
|  | read_fp_test (1, scaling_factor, BFD_ENDIAN_BIG, expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  | read_fp_test (1, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  |  | 
|  | read_fp_test (1025, scaling_factor, BFD_ENDIAN_BIG, expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  | read_fp_test (1025, scaling_factor, BFD_ENDIAN_LITTLE, expected, actual); | 
|  | SELF_CHECK (actual == expected); | 
|  | } | 
|  |  | 
|  | /* A helper function which builds a gdb_mpq object from the given | 
|  | NUMERATOR and DENOMINATOR, and then calls gdb_mpq's write_fixed_point | 
|  | method to write it to a buffer. | 
|  |  | 
|  | The value written into the buffer is then read back as is, | 
|  | and returned.  */ | 
|  |  | 
|  | static LONGEST | 
|  | write_fp_test (int numerator, unsigned int denominator, | 
|  | const gdb_mpq &scaling_factor, | 
|  | enum bfd_endian byte_order) | 
|  | { | 
|  | /* For this testing, we'll use a buffer the size of LONGEST. | 
|  | This is really an arbitrary decision, as long as the buffer | 
|  | is long enough to hold the unscaled values that we'll be | 
|  | writing.  */ | 
|  | const size_t len = sizeof (LONGEST); | 
|  | gdb_byte buf[len]; | 
|  | memset (buf, 0, len); | 
|  |  | 
|  | gdb_mpq v (numerator, denominator); | 
|  | v.write_fixed_point ({buf, len}, byte_order, 0, scaling_factor); | 
|  |  | 
|  | return extract_unsigned_integer (buf, len, byte_order); | 
|  | } | 
|  |  | 
|  | /* Perform various tests of the gdb_mpq::write_fixed_point method.  */ | 
|  |  | 
|  | static void | 
|  | gdb_mpq_write_fixed_point () | 
|  | { | 
|  | /* Pick an arbitrary factor; this operations is sufficiently trivial | 
|  | with the use of GMP that the value of this factor is not really | 
|  | all that important.  */ | 
|  | gdb_mpq scaling_factor (1, 3); | 
|  |  | 
|  | gdb_mpq vq; | 
|  |  | 
|  | /* Try a few multiples of the scaling factor, both negative, | 
|  | and positive... */ | 
|  |  | 
|  | SELF_CHECK (write_fp_test (-8, 1, scaling_factor, BFD_ENDIAN_BIG) == -24); | 
|  | SELF_CHECK (write_fp_test (-8, 1, scaling_factor, BFD_ENDIAN_LITTLE) == -24); | 
|  |  | 
|  | SELF_CHECK (write_fp_test (-2, 3, scaling_factor, BFD_ENDIAN_BIG) == -2); | 
|  | SELF_CHECK (write_fp_test (-2, 3, scaling_factor, BFD_ENDIAN_LITTLE) == -2); | 
|  |  | 
|  | SELF_CHECK (write_fp_test (0, 3, scaling_factor, BFD_ENDIAN_BIG) == 0); | 
|  | SELF_CHECK (write_fp_test (0, 3, scaling_factor, BFD_ENDIAN_LITTLE) == 0); | 
|  |  | 
|  | SELF_CHECK (write_fp_test (5, 3, scaling_factor, BFD_ENDIAN_BIG) == 5); | 
|  | SELF_CHECK (write_fp_test (5, 3, scaling_factor, BFD_ENDIAN_LITTLE) == 5); | 
|  | } | 
|  |  | 
|  | } | 
|  |  | 
|  | void _initialize_gmp_utils_selftests (); | 
|  |  | 
|  | void | 
|  | _initialize_gmp_utils_selftests () | 
|  | { | 
|  | selftests::register_test ("gdb_mpz_as_integer", | 
|  | selftests::gdb_mpz_as_integer); | 
|  | selftests::register_test ("gdb_mpz_as_integer_out_of_range", | 
|  | selftests::gdb_mpz_as_integer_out_of_range); | 
|  | selftests::register_test ("gdb_mpz_read_all_from_small", | 
|  | selftests::gdb_mpz_read_all_from_small); | 
|  | selftests::register_test ("gdb_mpz_read_min_max", | 
|  | selftests::gdb_mpz_read_min_max); | 
|  | selftests::register_test ("gdb_mpz_write_all_from_small", | 
|  | selftests::gdb_mpz_write_all_from_small); | 
|  | selftests::register_test ("gdb_mpz_write_min_max", | 
|  | selftests::gdb_mpz_write_min_max); | 
|  | selftests::register_test ("gdb_mpq_read_fixed_point", | 
|  | selftests::gdb_mpq_read_fixed_point); | 
|  | selftests::register_test ("gdb_mpq_write_fixed_point", | 
|  | selftests::gdb_mpq_write_fixed_point); | 
|  | } |