Blame gl/tests/test-intprops.c

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