Blame gnulib-tests/test-intprops.c

Packit 709fb3
/* Test intprops.h.
Packit 709fb3
   Copyright (C) 2011-2017 Free Software Foundation, Inc.
Packit 709fb3
Packit 709fb3
   This program is free software: you can redistribute it and/or modify
Packit 709fb3
   it under the terms of the GNU General Public License as published by
Packit 709fb3
   the Free Software Foundation; either version 3 of the License, or
Packit 709fb3
   (at your option) any later version.
Packit 709fb3
Packit 709fb3
   This program is distributed in the hope that it will be useful,
Packit 709fb3
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 709fb3
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 709fb3
   GNU General Public License for more details.
Packit 709fb3
Packit 709fb3
   You should have received a copy of the GNU General Public License
Packit 709fb3
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit 709fb3
Packit 709fb3
/* Written by Paul Eggert.  */
Packit 709fb3
Packit 709fb3
/* Tell gcc not to warn about the long expressions that the overflow
Packit 709fb3
   macros expand to, or about the (X < 0) expressions.  */
Packit 709fb3
#if 4 < __GNUC__ + (3 <= __GNUC_MINOR__)
Packit 709fb3
# pragma GCC diagnostic ignored "-Woverlength-strings"
Packit 709fb3
# pragma GCC diagnostic ignored "-Wtype-limits"
Packit 709fb3
Packit 709fb3
/* Work around a bug in GCC 6.1 and earlier; see:
Packit 709fb3
   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68971  */
Packit 709fb3
# pragma GCC diagnostic ignored "-Woverflow"
Packit 709fb3
Packit 709fb3
#endif
Packit 709fb3
Packit 709fb3
#include <config.h>
Packit 709fb3
Packit 709fb3
#include "intprops.h"
Packit 709fb3
#include "verify.h"
Packit 709fb3
Packit 709fb3
#include <stdbool.h>
Packit 709fb3
#include <inttypes.h>
Packit 709fb3
#include <limits.h>
Packit 709fb3
Packit 709fb3
#include "macros.h"
Packit 709fb3
Packit 709fb3
/* VERIFY (X) uses a static assertion for compilers that are known to work,
Packit 709fb3
   and falls back on a dynamic assertion for other compilers.
Packit 709fb3
   These tests should be checkable via 'verify' rather than 'ASSERT', but
Packit 709fb3
   using 'verify' would run into a bug with HP-UX 11.23 cc; see
Packit 709fb3
   <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00401.html>.  */
Packit 709fb3
#if __GNUC__ || __SUNPRO_C
Packit 709fb3
# define VERIFY(x) do { verify (x); } while (0)
Packit 709fb3
#else
Packit 709fb3
# define VERIFY(x) ASSERT (x)
Packit 709fb3
#endif
Packit 709fb3
Packit 709fb3
#define DONTCARE __LINE__
Packit 709fb3
Packit 709fb3
int
Packit 709fb3
main (void)
Packit 709fb3
{
Packit 709fb3
  /* Use VERIFY for tests that must be integer constant expressions,
Packit 709fb3
     ASSERT otherwise.  */
Packit 709fb3
Packit 709fb3
  /* TYPE_IS_INTEGER.  */
Packit 709fb3
  ASSERT (TYPE_IS_INTEGER (bool));
Packit 709fb3
  ASSERT (TYPE_IS_INTEGER (char));
Packit 709fb3
  ASSERT (TYPE_IS_INTEGER (signed char));
Packit 709fb3
  ASSERT (TYPE_IS_INTEGER (unsigned char));
Packit 709fb3
  ASSERT (TYPE_IS_INTEGER (short int));
Packit 709fb3
  ASSERT (TYPE_IS_INTEGER (unsigned short int));
Packit 709fb3
  ASSERT (TYPE_IS_INTEGER (int));
Packit 709fb3
  ASSERT (TYPE_IS_INTEGER (unsigned int));
Packit 709fb3
  ASSERT (TYPE_IS_INTEGER (long int));
Packit 709fb3
  ASSERT (TYPE_IS_INTEGER (unsigned long int));
Packit 709fb3
  ASSERT (TYPE_IS_INTEGER (intmax_t));
Packit 709fb3
  ASSERT (TYPE_IS_INTEGER (uintmax_t));
Packit 709fb3
  ASSERT (! TYPE_IS_INTEGER (float));
Packit 709fb3
  ASSERT (! TYPE_IS_INTEGER (double));
Packit 709fb3
  ASSERT (! TYPE_IS_INTEGER (long double));
Packit 709fb3
Packit 709fb3
  /* TYPE_SIGNED.  */
Packit 709fb3
  /* VERIFY (! TYPE_SIGNED (bool)); // not guaranteed by gnulib substitute */
Packit 709fb3
  VERIFY (TYPE_SIGNED (signed char));
Packit 709fb3
  VERIFY (! TYPE_SIGNED (unsigned char));
Packit 709fb3
  VERIFY (TYPE_SIGNED (short int));
Packit 709fb3
  VERIFY (! TYPE_SIGNED (unsigned short int));
Packit 709fb3
  VERIFY (TYPE_SIGNED (int));
Packit 709fb3
  VERIFY (! TYPE_SIGNED (unsigned int));
Packit 709fb3
  VERIFY (TYPE_SIGNED (long int));
Packit 709fb3
  VERIFY (! TYPE_SIGNED (unsigned long int));
Packit 709fb3
  VERIFY (TYPE_SIGNED (intmax_t));
Packit 709fb3
  VERIFY (! TYPE_SIGNED (uintmax_t));
Packit 709fb3
  ASSERT (TYPE_SIGNED (float));
Packit 709fb3
  ASSERT (TYPE_SIGNED (double));
Packit 709fb3
  ASSERT (TYPE_SIGNED (long double));
Packit 709fb3
Packit 709fb3
  /* Integer representation.  Check that it is two's complement.  */
Packit 709fb3
  VERIFY (INT_MIN + INT_MAX < 0);
Packit 709fb3
Packit 709fb3
  /* TYPE_MINIMUM, TYPE_MAXIMUM.  */
Packit 709fb3
  VERIFY (TYPE_MINIMUM (char) == CHAR_MIN);
Packit 709fb3
  VERIFY (TYPE_MAXIMUM (char) == CHAR_MAX);
Packit 709fb3
  VERIFY (TYPE_MINIMUM (unsigned char) == 0);
Packit 709fb3
  VERIFY (TYPE_MAXIMUM (unsigned char) == UCHAR_MAX);
Packit 709fb3
  VERIFY (TYPE_MINIMUM (signed char) == SCHAR_MIN);
Packit 709fb3
  VERIFY (TYPE_MAXIMUM (signed char) == SCHAR_MAX);
Packit 709fb3
  VERIFY (TYPE_MINIMUM (short int) == SHRT_MIN);
Packit 709fb3
  VERIFY (TYPE_MAXIMUM (short int) == SHRT_MAX);
Packit 709fb3
  VERIFY (TYPE_MINIMUM (unsigned short int) == 0);
Packit 709fb3
  VERIFY (TYPE_MAXIMUM (unsigned short int) == USHRT_MAX);
Packit 709fb3
  VERIFY (TYPE_MINIMUM (int) == INT_MIN);
Packit 709fb3
  VERIFY (TYPE_MAXIMUM (int) == INT_MAX);
Packit 709fb3
  VERIFY (TYPE_MINIMUM (unsigned int) == 0);
Packit 709fb3
  VERIFY (TYPE_MAXIMUM (unsigned int) == UINT_MAX);
Packit 709fb3
  VERIFY (TYPE_MINIMUM (long int) == LONG_MIN);
Packit 709fb3
  VERIFY (TYPE_MAXIMUM (long int) == LONG_MAX);
Packit 709fb3
  VERIFY (TYPE_MINIMUM (unsigned long int) == 0);
Packit 709fb3
  VERIFY (TYPE_MAXIMUM (unsigned long int) == ULONG_MAX);
Packit 709fb3
  #ifdef LLONG_MAX
Packit 709fb3
   verify (TYPE_MINIMUM (long long int) == LLONG_MIN);
Packit 709fb3
   verify (TYPE_MAXIMUM (long long int) == LLONG_MAX);
Packit 709fb3
  #endif
Packit 709fb3
  VERIFY (TYPE_MINIMUM (intmax_t) == INTMAX_MIN);
Packit 709fb3
  VERIFY (TYPE_MAXIMUM (intmax_t) == INTMAX_MAX);
Packit 709fb3
  VERIFY (TYPE_MINIMUM (uintmax_t) == 0);
Packit 709fb3
  VERIFY (TYPE_MAXIMUM (uintmax_t) == UINTMAX_MAX);
Packit 709fb3
Packit 709fb3
  /* TYPE_WIDTH.  */
Packit 709fb3
  #ifdef CHAR_WIDTH
Packit 709fb3
   verify (TYPE_WIDTH (char) == CHAR_WIDTH);
Packit 709fb3
   verify (TYPE_WIDTH (signed char) == SCHAR_WIDTH);
Packit 709fb3
   verify (TYPE_WIDTH (unsigned char) == UCHAR_WIDTH);
Packit 709fb3
   verify (TYPE_WIDTH (short int) == SHRT_WIDTH);
Packit 709fb3
   verify (TYPE_WIDTH (unsigned short int) == USHRT_WIDTH);
Packit 709fb3
   verify (TYPE_WIDTH (int) == INT_WIDTH);
Packit 709fb3
   verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH);
Packit 709fb3
   verify (TYPE_WIDTH (long int) == LONG_WIDTH);
Packit 709fb3
   verify (TYPE_WIDTH (unsigned long int) == ULONG_WIDTH);
Packit 709fb3
   #ifdef LLONG_WIDTH
Packit 709fb3
    verify (TYPE_WIDTH (long long int) == LLONG_WIDTH);
Packit 709fb3
    verify (TYPE_WIDTH (unsigned long long int) == ULLONG_WIDTH);
Packit 709fb3
   #endif
Packit 709fb3
  #endif
Packit 709fb3
Packit 709fb3
  /* INT_BITS_STRLEN_BOUND.  */
Packit 709fb3
  VERIFY (INT_BITS_STRLEN_BOUND (1) == 1);
Packit 709fb3
  VERIFY (INT_BITS_STRLEN_BOUND (2620) == 789);
Packit 709fb3
Packit 709fb3
  /* INT_STRLEN_BOUND, INT_BUFSIZE_BOUND.  */
Packit 709fb3
  #ifdef INT32_MAX /* POSIX guarantees int32_t; this ports to non-POSIX.  */
Packit 709fb3
  VERIFY (INT_STRLEN_BOUND (int32_t) == sizeof ("-2147483648") - 1);
Packit 709fb3
  VERIFY (INT_BUFSIZE_BOUND (int32_t) == sizeof ("-2147483648"));
Packit 709fb3
  #endif
Packit 709fb3
  #ifdef INT64_MAX
Packit 709fb3
  VERIFY (INT_STRLEN_BOUND (int64_t) == sizeof ("-9223372036854775808") - 1);
Packit 709fb3
  VERIFY (INT_BUFSIZE_BOUND (int64_t) == sizeof ("-9223372036854775808"));
Packit 709fb3
  #endif
Packit 709fb3
Packit 709fb3
  /* All the INT_<op>_RANGE_OVERFLOW tests are equally valid as
Packit 709fb3
     INT_<op>_OVERFLOW tests, so define macros to do both.  OP is the
Packit 709fb3
     operation, OPNAME its symbolic name, A and B its operands, T the
Packit 709fb3
     result type, V the overflow flag, and VRES the result if V and if
Packit 709fb3
     two's complement.  CHECK_BINOP is for most binary operatinos,
Packit 709fb3
     CHECK_SBINOP for binary +, -, * when the result type is signed,
Packit 709fb3
     and CHECK_UNOP for unary operations.  */
Packit 709fb3
  #define CHECK_BINOP(op, opname, a, b, t, v, vres)                       \
Packit 709fb3
    VERIFY (INT_##opname##_RANGE_OVERFLOW (a, b, TYPE_MINIMUM (t),        \
Packit 709fb3
                                           TYPE_MAXIMUM (t))              \
Packit 709fb3
            == (v));                                                      \
Packit 709fb3
    VERIFY (INT_##opname##_OVERFLOW (a, b) == (v))
Packit 709fb3
  #define CHECK_SBINOP(op, opname, a, b, t, v, vres)                      \
Packit 709fb3
    CHECK_BINOP(op, opname, a, b, t, v, vres);                            \
Packit 709fb3
    {                                                                     \
Packit 709fb3
      t result;                                                           \
Packit 709fb3
      ASSERT (INT_##opname##_WRAPV (a, b, &result) == (v));               \
Packit 709fb3
      ASSERT (result == ((v) ? (vres) : ((a) op (b))));                   \
Packit 709fb3
    }
Packit 709fb3
  #define CHECK_UNOP(op, opname, a, t, v)                                 \
Packit 709fb3
    VERIFY (INT_##opname##_RANGE_OVERFLOW (a, TYPE_MINIMUM (t),           \
Packit 709fb3
                                           TYPE_MAXIMUM (t))              \
Packit 709fb3
            == (v));                                                      \
Packit 709fb3
    VERIFY (INT_##opname##_OVERFLOW (a) == (v))
Packit 709fb3
Packit 709fb3
  /* INT_<op>_RANGE_OVERFLOW, INT_<op>_OVERFLOW.  */
Packit 709fb3
  VERIFY (INT_ADD_RANGE_OVERFLOW (INT_MAX, 1, INT_MIN, INT_MAX));
Packit 709fb3
  VERIFY (INT_ADD_OVERFLOW (INT_MAX, 1));
Packit 709fb3
Packit 709fb3
  CHECK_SBINOP (+, ADD, INT_MAX, 1, int, true, INT_MIN);
Packit 709fb3
  CHECK_SBINOP (+, ADD, INT_MAX, -1, int, false, INT_MAX - 1);
Packit 709fb3
  CHECK_SBINOP (+, ADD, INT_MIN, 1, int, false, INT_MIN + 1);
Packit 709fb3
  CHECK_SBINOP (+, ADD, INT_MIN, -1, int, true, INT_MAX);
Packit 709fb3
  CHECK_BINOP (+, ADD, UINT_MAX, 1u, unsigned int, true, 0u);
Packit 709fb3
  CHECK_BINOP (+, ADD, 0u, 1u, unsigned int, false, 1u);
Packit 709fb3
Packit 709fb3
  CHECK_SBINOP (-, SUBTRACT, INT_MAX, 1, int, false, INT_MAX - 1);
Packit 709fb3
  CHECK_SBINOP (-, SUBTRACT, INT_MAX, -1, int, true, INT_MIN);
Packit 709fb3
  CHECK_SBINOP (-, SUBTRACT, INT_MIN, 1, int, true, INT_MAX);
Packit 709fb3
  CHECK_SBINOP (-, SUBTRACT, INT_MIN, -1, int, false, INT_MIN - -1);
Packit 709fb3
  CHECK_BINOP (-, SUBTRACT, UINT_MAX, 1u, unsigned int, false, UINT_MAX - 1u);
Packit 709fb3
  CHECK_BINOP (-, SUBTRACT, 0u, 1u, unsigned int, true, 0u - 1u);
Packit 709fb3
Packit 709fb3
  CHECK_UNOP (-, NEGATE, INT_MIN, int, true);
Packit 709fb3
  CHECK_UNOP (-, NEGATE, 0, int, false);
Packit 709fb3
  CHECK_UNOP (-, NEGATE, INT_MAX, int, false);
Packit 709fb3
  CHECK_UNOP (-, NEGATE, 0u, unsigned int, false);
Packit 709fb3
  CHECK_UNOP (-, NEGATE, 1u, unsigned int, true);
Packit 709fb3
  CHECK_UNOP (-, NEGATE, UINT_MAX, unsigned int, true);
Packit 709fb3
Packit 709fb3
  CHECK_SBINOP (*, MULTIPLY, INT_MAX, INT_MAX, int, true, 1);
Packit 709fb3
  CHECK_SBINOP (*, MULTIPLY, INT_MAX, INT_MIN, int, true, INT_MIN);
Packit 709fb3
  CHECK_SBINOP (*, MULTIPLY, INT_MIN, INT_MAX, int, true, INT_MIN);
Packit 709fb3
  CHECK_SBINOP (*, MULTIPLY, INT_MIN, INT_MIN, int, true, 0);
Packit 709fb3
  CHECK_SBINOP (*, MULTIPLY, -1, INT_MIN, int,
Packit 709fb3
                INT_NEGATE_OVERFLOW (INT_MIN), INT_MIN);
Packit 709fb3
  CHECK_SBINOP (*, MULTIPLY, LONG_MIN / INT_MAX, (long int) INT_MAX,
Packit 709fb3
                long int, false, LONG_MIN - LONG_MIN % INT_MAX);
Packit 709fb3
Packit 709fb3
  CHECK_BINOP (/, DIVIDE, INT_MIN, -1, int,
Packit 709fb3
               INT_NEGATE_OVERFLOW (INT_MIN), INT_MIN);
Packit 709fb3
  CHECK_BINOP (/, DIVIDE, INT_MAX, 1, int, false, INT_MAX);
Packit 709fb3
  CHECK_BINOP (/, DIVIDE, (unsigned int) INT_MIN, -1u, unsigned int,
Packit 709fb3
               false, INT_MIN / -1u);
Packit 709fb3
Packit 709fb3
  CHECK_BINOP (%, REMAINDER, INT_MIN, -1, int, INT_NEGATE_OVERFLOW (INT_MIN), 0);
Packit 709fb3
  CHECK_BINOP (%, REMAINDER, INT_MAX, 1, int, false, 0);
Packit 709fb3
  CHECK_BINOP (%, REMAINDER, (unsigned int) INT_MIN, -1u, unsigned int,
Packit 709fb3
               false, INT_MIN % -1u);
Packit 709fb3
Packit 709fb3
  CHECK_BINOP (<<, LEFT_SHIFT, UINT_MAX, 1, unsigned int, true, UINT_MAX << 1);
Packit 709fb3
  CHECK_BINOP (<<, LEFT_SHIFT, UINT_MAX / 2 + 1, 1, unsigned int, true,
Packit 709fb3
               (UINT_MAX / 2 + 1) << 1);
Packit 709fb3
  CHECK_BINOP (<<, LEFT_SHIFT, UINT_MAX / 2, 1, unsigned int, false,
Packit 709fb3
               (UINT_MAX / 2) << 1);
Packit 709fb3
Packit 709fb3
  /* INT_<op>_OVERFLOW and INT_<op>_WRAPV with mixed types.  */
Packit 709fb3
  #define CHECK_SUM(a, b, t, v, vres)                                     \
Packit 709fb3
    CHECK_SUM1(a, b, t, v, vres);                                         \
Packit 709fb3
    CHECK_SUM1(b, a, t, v, vres)
Packit 709fb3
  #define CHECK_SSUM(a, b, t, v, vres)                                    \
Packit 709fb3
    CHECK_SSUM1(a, b, t, v, vres);                                        \
Packit 709fb3
    CHECK_SSUM1(b, a, t, v, vres)
Packit 709fb3
  #define CHECK_SUM1(a, b, t, v, vres)                                    \
Packit 709fb3
    VERIFY (INT_ADD_OVERFLOW (a, b) == (v))
Packit 709fb3
  #define CHECK_SSUM1(a, b, t, v, vres)                                   \
Packit 709fb3
    CHECK_SUM1(a, b, t, v, vres);                                         \
Packit 709fb3
    {                                                                     \
Packit 709fb3
      t result;                                                           \
Packit 709fb3
      ASSERT (INT_ADD_WRAPV (a, b, &result) == (v));                      \
Packit 709fb3
      ASSERT (result == ((v) ? (vres) : ((a) + (b))));                    \
Packit 709fb3
    }
Packit 709fb3
  CHECK_SSUM (-1, LONG_MIN, long int, true, LONG_MAX);
Packit 709fb3
  CHECK_SUM (-1, UINT_MAX, unsigned int, false, DONTCARE);
Packit 709fb3
  CHECK_SSUM (-1L, INT_MIN, long int, INT_MIN == LONG_MIN,
Packit 709fb3
              INT_MIN == LONG_MIN ? INT_MAX : DONTCARE);
Packit 709fb3
  CHECK_SUM (0u, -1, unsigned int, true, 0u + -1);
Packit 709fb3
  CHECK_SUM (0u, 0, unsigned int, false, DONTCARE);
Packit 709fb3
  CHECK_SUM (0u, 1, unsigned int, false, DONTCARE);
Packit 709fb3
  CHECK_SSUM (1, LONG_MAX, long int, true, LONG_MIN);
Packit 709fb3
  CHECK_SUM (1, UINT_MAX, unsigned int, true, 0u);
Packit 709fb3
  CHECK_SSUM (1L, INT_MAX, long int, INT_MAX == LONG_MAX,
Packit 709fb3
              INT_MAX == LONG_MAX ? INT_MIN : DONTCARE);
Packit 709fb3
  CHECK_SUM (1u, INT_MAX, unsigned int, INT_MAX == UINT_MAX, 1u + INT_MAX);
Packit 709fb3
  CHECK_SUM (1u, INT_MIN, unsigned int, true, 1u + INT_MIN);
Packit 709fb3
  {
Packit 709fb3
    long int result;
Packit 709fb3
    ASSERT (INT_ADD_WRAPV (1, INT_MAX, &result) == (INT_MAX == LONG_MAX));
Packit 709fb3
    ASSERT (INT_ADD_WRAPV (-1, INT_MIN, &result) == (INT_MIN == LONG_MIN));
Packit 709fb3
  }
Packit 709fb3
Packit 709fb3
  #define CHECK_DIFFERENCE(a, b, t, v, vres)                              \
Packit 709fb3
    VERIFY (INT_SUBTRACT_OVERFLOW (a, b) == (v))
Packit 709fb3
  #define CHECK_SDIFFERENCE(a, b, t, v, vres)                             \
Packit 709fb3
    CHECK_DIFFERENCE(a, b, t, v, vres);                                   \
Packit 709fb3
    {                                                                     \
Packit 709fb3
      t result;                                                           \
Packit 709fb3
      ASSERT (INT_SUBTRACT_WRAPV (a, b, &result) == (v));                 \
Packit 709fb3
      ASSERT (result == ((v) ? (vres) : ((a) - (b))));                    \
Packit 709fb3
    }
Packit 709fb3
  CHECK_DIFFERENCE (INT_MAX, 1u, unsigned int, UINT_MAX < INT_MAX - 1,
Packit 709fb3
                    INT_MAX - 1u);
Packit 709fb3
  CHECK_DIFFERENCE (UINT_MAX, 1, unsigned int, false, UINT_MAX - 1);
Packit 709fb3
  CHECK_DIFFERENCE (0u, -1, unsigned int, false, 0u - -1);
Packit 709fb3
  CHECK_DIFFERENCE (UINT_MAX, -1, unsigned int, true, UINT_MAX - -1);
Packit 709fb3
  CHECK_DIFFERENCE (INT_MIN, 1u, unsigned int, true, INT_MIN - 1u);
Packit 709fb3
  CHECK_DIFFERENCE (-1, 0u, unsigned int, true, -1 - 0u);
Packit 709fb3
  CHECK_SDIFFERENCE (-1, INT_MIN, int, false, -1 - INT_MIN);
Packit 709fb3
  CHECK_SDIFFERENCE (-1, INT_MAX, int, false, -1 - INT_MAX);
Packit 709fb3
  CHECK_SDIFFERENCE (0, INT_MIN, int, INT_MIN < -INT_MAX, INT_MIN);
Packit 709fb3
  CHECK_SDIFFERENCE (0, INT_MAX, int, false, 0 - INT_MAX);
Packit 709fb3
  {
Packit 709fb3
    long int result;
Packit 709fb3
    ASSERT (INT_SUBTRACT_WRAPV (INT_MAX, -1, &result) == (INT_MAX == LONG_MAX));
Packit 709fb3
    ASSERT (INT_SUBTRACT_WRAPV (INT_MIN, 1, &result) == (INT_MAX == LONG_MAX));
Packit 709fb3
  }
Packit 709fb3
Packit 709fb3
  #define CHECK_PRODUCT(a, b, t, v, vres)                                 \
Packit 709fb3
    CHECK_PRODUCT1(a, b, t, v, vres);                                     \
Packit 709fb3
    CHECK_PRODUCT1(b, a, t, v, vres)
Packit 709fb3
  #define CHECK_SPRODUCT(a, b, t, v, vres)                                \
Packit 709fb3
    CHECK_SPRODUCT1(a, b, t, v, vres);                                    \
Packit 709fb3
    CHECK_SPRODUCT1(b, a, t, v, vres)
Packit 709fb3
  #define CHECK_PRODUCT1(a, b, t, v, vres)                                \
Packit 709fb3
    VERIFY (INT_MULTIPLY_OVERFLOW (a, b) == (v))
Packit 709fb3
  #define CHECK_SPRODUCT1(a, b, t, v, vres)                               \
Packit 709fb3
    CHECK_PRODUCT1(a, b, t, v, vres);                                     \
Packit 709fb3
    {                                                                     \
Packit 709fb3
      t result;                                                           \
Packit 709fb3
      ASSERT (INT_MULTIPLY_WRAPV (a, b, &result) == (v));                 \
Packit 709fb3
      ASSERT (result == ((v) ? (vres) : ((a) * (b))));                    \
Packit 709fb3
    }
Packit 709fb3
  CHECK_PRODUCT (-1, 1u, unsigned int, true, -1 * 1u);
Packit 709fb3
  CHECK_SPRODUCT (-1, INT_MIN, int, INT_NEGATE_OVERFLOW (INT_MIN), INT_MIN);
Packit 709fb3
  CHECK_PRODUCT (-1, UINT_MAX, unsigned int, true, -1 * UINT_MAX);
Packit 709fb3
  CHECK_SPRODUCT (-32768, LONG_MAX / -32768 - 1, long int, true, LONG_MIN);
Packit 709fb3
  CHECK_SPRODUCT (-12345, LONG_MAX / -12345, long int, false, DONTCARE);
Packit 709fb3
  CHECK_SPRODUCT (0, -1, int, false, DONTCARE);
Packit 709fb3
  CHECK_SPRODUCT (0, 0, int, false, DONTCARE);
Packit 709fb3
  CHECK_PRODUCT (0, 0u, unsigned int, false, DONTCARE);
Packit 709fb3
  CHECK_SPRODUCT (0, 1, int, false, DONTCARE);
Packit 709fb3
  CHECK_SPRODUCT (0, INT_MAX, int, false, DONTCARE);
Packit 709fb3
  CHECK_SPRODUCT (0, INT_MIN, int, false, DONTCARE);
Packit 709fb3
  CHECK_PRODUCT (0, UINT_MAX, unsigned int, false, DONTCARE);
Packit 709fb3
  CHECK_PRODUCT (0u, -1, unsigned int, false, DONTCARE);
Packit 709fb3
  CHECK_PRODUCT (0u, 0, unsigned int, false, DONTCARE);
Packit 709fb3
  CHECK_PRODUCT (0u, 0u, unsigned int, false, DONTCARE);
Packit 709fb3
  CHECK_PRODUCT (0u, 1, unsigned int, false, DONTCARE);
Packit 709fb3
  CHECK_PRODUCT (0u, INT_MAX, unsigned int, false, DONTCARE);
Packit 709fb3
  CHECK_PRODUCT (0u, INT_MIN, unsigned int, false, DONTCARE);
Packit 709fb3
  CHECK_PRODUCT (0u, UINT_MAX, unsigned int, false, DONTCARE);
Packit 709fb3
  CHECK_SPRODUCT (1, INT_MAX, int, false, DONTCARE);
Packit 709fb3
  CHECK_SPRODUCT (1, INT_MIN, int, false, DONTCARE);
Packit 709fb3
  CHECK_PRODUCT (1, UINT_MAX, unsigned int, false, DONTCARE);
Packit 709fb3
  CHECK_PRODUCT (1u, INT_MIN, unsigned int, true, 1u * INT_MIN);
Packit 709fb3
  CHECK_PRODUCT (1u, INT_MAX, unsigned int, UINT_MAX < INT_MAX, 1u * INT_MAX);
Packit 709fb3
  CHECK_PRODUCT (INT_MAX, UINT_MAX, unsigned int, true, INT_MAX * UINT_MAX);
Packit 709fb3
  CHECK_PRODUCT (INT_MAX, ULONG_MAX, unsigned long int, true,
Packit 709fb3
                 INT_MAX * ULONG_MAX);
Packit 709fb3
  CHECK_SPRODUCT (INT_MIN, LONG_MAX / INT_MIN - 1, long int, true, LONG_MIN);
Packit 709fb3
  CHECK_SPRODUCT (INT_MIN, LONG_MAX / INT_MIN, long int, false, DONTCARE);
Packit 709fb3
  CHECK_PRODUCT (INT_MIN, UINT_MAX, unsigned int, true, INT_MIN * UINT_MAX);
Packit 709fb3
  CHECK_PRODUCT (INT_MIN, ULONG_MAX, unsigned long int, true,
Packit 709fb3
                 INT_MIN * ULONG_MAX);
Packit 709fb3
  {
Packit 709fb3
    long int result;
Packit 709fb3
    ASSERT (INT_MULTIPLY_WRAPV (INT_MAX, INT_MAX, &result)
Packit 709fb3
            == (LONG_MAX / INT_MAX < INT_MAX));
Packit 709fb3
    ASSERT (INT_MULTIPLY_WRAPV (INT_MAX, INT_MAX, &result)
Packit 709fb3
            || result == INT_MAX * (long int) INT_MAX);
Packit 709fb3
    ASSERT (INT_MULTIPLY_WRAPV (INT_MIN, INT_MIN, &result)
Packit 709fb3
            || result == INT_MIN * (long int) INT_MIN);
Packit 709fb3
  }
Packit 709fb3
Packit 709fb3
# ifdef LLONG_MAX
Packit 709fb3
  {
Packit 709fb3
    long long int result;
Packit 709fb3
    ASSERT (INT_MULTIPLY_WRAPV (LONG_MAX, LONG_MAX, &result)
Packit 709fb3
            == (LLONG_MAX / LONG_MAX < LONG_MAX));
Packit 709fb3
    ASSERT (INT_MULTIPLY_WRAPV (LONG_MAX, LONG_MAX, &result)
Packit 709fb3
            || result == LONG_MAX * (long long int) LONG_MAX);
Packit 709fb3
    ASSERT (INT_MULTIPLY_WRAPV (LONG_MIN, LONG_MIN, &result)
Packit 709fb3
            || result == LONG_MIN * (long long int) LONG_MIN);
Packit 709fb3
  }
Packit 709fb3
# endif
Packit 709fb3
Packit 709fb3
  #define CHECK_QUOTIENT(a, b, v) VERIFY (INT_DIVIDE_OVERFLOW (a, b) == (v))
Packit 709fb3
Packit 709fb3
  CHECK_QUOTIENT (INT_MIN, -1L, INT_MIN == LONG_MIN);
Packit 709fb3
  CHECK_QUOTIENT (INT_MIN, UINT_MAX, false);
Packit 709fb3
  CHECK_QUOTIENT (INTMAX_MIN, UINTMAX_MAX, false);
Packit 709fb3
  CHECK_QUOTIENT (INTMAX_MIN, UINT_MAX, false);
Packit 709fb3
  CHECK_QUOTIENT (-11, 10u, true);
Packit 709fb3
  CHECK_QUOTIENT (-10, 10u, true);
Packit 709fb3
  CHECK_QUOTIENT (-9, 10u, false);
Packit 709fb3
  CHECK_QUOTIENT (11u, -10, true);
Packit 709fb3
  CHECK_QUOTIENT (10u, -10, true);
Packit 709fb3
  CHECK_QUOTIENT (9u, -10, false);
Packit 709fb3
Packit 709fb3
  #define CHECK_REMAINDER(a, b, v) VERIFY (INT_REMAINDER_OVERFLOW (a, b) == (v))
Packit 709fb3
Packit 709fb3
  CHECK_REMAINDER (INT_MIN, -1L, INT_MIN == LONG_MIN);
Packit 709fb3
  CHECK_REMAINDER (-1, UINT_MAX, true);
Packit 709fb3
  CHECK_REMAINDER ((intmax_t) -1, UINTMAX_MAX, true);
Packit 709fb3
  CHECK_REMAINDER (INTMAX_MIN, UINT_MAX,
Packit 709fb3
                   (INTMAX_MAX < UINT_MAX
Packit 709fb3
                    && - (unsigned int) INTMAX_MIN % UINT_MAX != 0));
Packit 709fb3
  CHECK_REMAINDER (INT_MIN, ULONG_MAX, INT_MIN % ULONG_MAX != 1);
Packit 709fb3
  CHECK_REMAINDER (1u, -1, false);
Packit 709fb3
  CHECK_REMAINDER (37*39u, -39, false);
Packit 709fb3
  CHECK_REMAINDER (37*39u + 1, -39, true);
Packit 709fb3
  CHECK_REMAINDER (37*39u - 1, -39, true);
Packit 709fb3
  CHECK_REMAINDER (LONG_MAX, -INT_MAX, false);
Packit 709fb3
Packit 709fb3
  return 0;
Packit 709fb3
}