(root)/
grep-3.11/
gnulib-tests/
test-intprops.c
       1  /* Test intprops.h.
       2     Copyright (C) 2011-2023 Free Software Foundation, Inc.
       3  
       4     This program is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation, either version 3 of the License, or
       7     (at your option) any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  /* Written by Paul Eggert.  */
      18  
      19  /* Tell gcc not to warn about the long expressions that the overflow
      20     macros expand to, or about the (X < 0) expressions.  */
      21  #if 4 < __GNUC__ + (3 <= __GNUC_MINOR__)
      22  # pragma GCC diagnostic ignored "-Woverlength-strings"
      23  # pragma GCC diagnostic ignored "-Wtype-limits"
      24  
      25  /* Work around a bug in GCC 6.1 and earlier; see:
      26     https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68971  */
      27  # pragma GCC diagnostic ignored "-Woverflow"
      28  
      29  #endif
      30  
      31  #include <config.h>
      32  
      33  #ifdef TEST_STDCKDINT
      34  # include <stdckdint.h>
      35  #else
      36  # include "intprops.h"
      37  #endif
      38  
      39  #include <inttypes.h>
      40  #include <limits.h>
      41  
      42  #include "macros.h"
      43  
      44  /* Compile-time verification of expression X.
      45     In this file, we need it as a statement, rather than as a declaration.  */
      46  #define verify_stmt(x) do { static_assert (x); } while (0)
      47  
      48  /* VERIFY (X) uses a static assertion for compilers that are known to work,
      49     and falls back on a dynamic assertion for other compilers.
      50     But it ignores X if testing stdckdint.h.
      51     These tests should be checkable via 'verify' rather than 'ASSERT', but
      52     using 'verify' would run into a bug with HP-UX 11.23 cc; see
      53     <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00401.html>.  */
      54  #ifdef TEST_STDCKDINT
      55  # define VERIFY(x) ((void) 0)
      56  #elif __GNUC__ || __clang__ || __SUNPRO_C
      57  # define VERIFY(x) verify_stmt (x)
      58  #else
      59  # define VERIFY(x) ASSERT (x)
      60  #endif
      61  
      62  #define DONTCARE __LINE__
      63  
      64  int int_minus_2 = -2;
      65  int int_1 = 1;
      66  
      67  int
      68  main (void)
      69  {
      70    /* Use VERIFY for tests that must be integer constant expressions,
      71       ASSERT otherwise.  */
      72  
      73  #ifndef TEST_STDCKDINT
      74    /* TYPE_IS_INTEGER.  */
      75    ASSERT (TYPE_IS_INTEGER (bool));
      76    ASSERT (TYPE_IS_INTEGER (char));
      77    ASSERT (TYPE_IS_INTEGER (signed char));
      78    ASSERT (TYPE_IS_INTEGER (unsigned char));
      79    ASSERT (TYPE_IS_INTEGER (short int));
      80    ASSERT (TYPE_IS_INTEGER (unsigned short int));
      81    ASSERT (TYPE_IS_INTEGER (int));
      82    ASSERT (TYPE_IS_INTEGER (unsigned int));
      83    ASSERT (TYPE_IS_INTEGER (long int));
      84    ASSERT (TYPE_IS_INTEGER (unsigned long int));
      85    ASSERT (TYPE_IS_INTEGER (intmax_t));
      86    ASSERT (TYPE_IS_INTEGER (uintmax_t));
      87    ASSERT (! TYPE_IS_INTEGER (float));
      88    ASSERT (! TYPE_IS_INTEGER (double));
      89    ASSERT (! TYPE_IS_INTEGER (long double));
      90  
      91    /* TYPE_SIGNED.  */
      92    /* VERIFY (! TYPE_SIGNED (bool)); // not guaranteed by gnulib substitute */
      93    VERIFY (TYPE_SIGNED (signed char));
      94    VERIFY (! TYPE_SIGNED (unsigned char));
      95    VERIFY (TYPE_SIGNED (short int));
      96    VERIFY (! TYPE_SIGNED (unsigned short int));
      97    VERIFY (TYPE_SIGNED (int));
      98    VERIFY (! TYPE_SIGNED (unsigned int));
      99    VERIFY (TYPE_SIGNED (long int));
     100    VERIFY (! TYPE_SIGNED (unsigned long int));
     101    VERIFY (TYPE_SIGNED (intmax_t));
     102    VERIFY (! TYPE_SIGNED (uintmax_t));
     103    ASSERT (TYPE_SIGNED (float));
     104    ASSERT (TYPE_SIGNED (double));
     105    ASSERT (TYPE_SIGNED (long double));
     106  
     107    /* Integer representation.  Check that it is two's complement.  */
     108    VERIFY (INT_MIN + INT_MAX < 0);
     109  
     110    /* TYPE_MINIMUM, TYPE_MAXIMUM.  */
     111    VERIFY (TYPE_MINIMUM (char) == CHAR_MIN);
     112    VERIFY (TYPE_MAXIMUM (char) == CHAR_MAX);
     113    VERIFY (TYPE_MINIMUM (unsigned char) == 0);
     114    VERIFY (TYPE_MAXIMUM (unsigned char) == UCHAR_MAX);
     115    VERIFY (TYPE_MINIMUM (signed char) == SCHAR_MIN);
     116    VERIFY (TYPE_MAXIMUM (signed char) == SCHAR_MAX);
     117    VERIFY (TYPE_MINIMUM (short int) == SHRT_MIN);
     118    VERIFY (TYPE_MAXIMUM (short int) == SHRT_MAX);
     119    VERIFY (TYPE_MINIMUM (unsigned short int) == 0);
     120    VERIFY (TYPE_MAXIMUM (unsigned short int) == USHRT_MAX);
     121    VERIFY (TYPE_MINIMUM (int) == INT_MIN);
     122    VERIFY (TYPE_MAXIMUM (int) == INT_MAX);
     123    VERIFY (TYPE_MINIMUM (unsigned int) == 0);
     124    VERIFY (TYPE_MAXIMUM (unsigned int) == UINT_MAX);
     125    VERIFY (TYPE_MINIMUM (long int) == LONG_MIN);
     126    VERIFY (TYPE_MAXIMUM (long int) == LONG_MAX);
     127    VERIFY (TYPE_MINIMUM (unsigned long int) == 0);
     128    VERIFY (TYPE_MAXIMUM (unsigned long int) == ULONG_MAX);
     129    #ifdef LLONG_MAX
     130     verify_stmt (TYPE_MINIMUM (long long int) == LLONG_MIN);
     131     verify_stmt (TYPE_MAXIMUM (long long int) == LLONG_MAX);
     132     verify_stmt (TYPE_MINIMUM (unsigned long long int) == 0);
     133     verify_stmt (TYPE_MAXIMUM (unsigned long long int) == ULLONG_MAX);
     134    #endif
     135    VERIFY (TYPE_MINIMUM (intmax_t) == INTMAX_MIN);
     136    VERIFY (TYPE_MAXIMUM (intmax_t) == INTMAX_MAX);
     137    VERIFY (TYPE_MINIMUM (uintmax_t) == 0);
     138    VERIFY (TYPE_MAXIMUM (uintmax_t) == UINTMAX_MAX);
     139  
     140    /* TYPE_WIDTH.  */
     141    #ifdef CHAR_WIDTH
     142     verify_stmt (TYPE_WIDTH (char) == CHAR_WIDTH);
     143     verify_stmt (TYPE_WIDTH (signed char) == SCHAR_WIDTH);
     144     verify_stmt (TYPE_WIDTH (unsigned char) == UCHAR_WIDTH);
     145     verify_stmt (TYPE_WIDTH (short int) == SHRT_WIDTH);
     146     verify_stmt (TYPE_WIDTH (unsigned short int) == USHRT_WIDTH);
     147     verify_stmt (TYPE_WIDTH (int) == INT_WIDTH);
     148     verify_stmt (TYPE_WIDTH (unsigned int) == UINT_WIDTH);
     149     verify_stmt (TYPE_WIDTH (long int) == LONG_WIDTH);
     150     verify_stmt (TYPE_WIDTH (unsigned long int) == ULONG_WIDTH);
     151     #ifdef LLONG_WIDTH
     152      verify_stmt (TYPE_WIDTH (long long int) == LLONG_WIDTH);
     153      verify_stmt (TYPE_WIDTH (unsigned long long int) == ULLONG_WIDTH);
     154     #endif
     155    #endif
     156  
     157    /* INT_BITS_STRLEN_BOUND.  */
     158    VERIFY (INT_BITS_STRLEN_BOUND (1) == 1);
     159    VERIFY (INT_BITS_STRLEN_BOUND (2620) == 789);
     160  
     161    /* INT_STRLEN_BOUND, INT_BUFSIZE_BOUND.  */
     162    #ifdef INT32_MAX /* POSIX guarantees int32_t; this ports to non-POSIX.  */
     163    VERIFY (INT_STRLEN_BOUND (int32_t) == sizeof ("-2147483648") - 1);
     164    VERIFY (INT_BUFSIZE_BOUND (int32_t) == sizeof ("-2147483648"));
     165    #endif
     166    #ifdef INT64_MAX
     167    VERIFY (INT_STRLEN_BOUND (int64_t) == sizeof ("-9223372036854775808") - 1);
     168    VERIFY (INT_BUFSIZE_BOUND (int64_t) == sizeof ("-9223372036854775808"));
     169    #endif
     170  #endif
     171  
     172    /* All the INT_<op>_RANGE_OVERFLOW tests are equally valid as
     173       INT_<op>_OVERFLOW tests, so define macros to do both.  OP is the
     174       operation, OPNAME its symbolic name, A and B its operands, T the
     175       result type, V the overflow flag, and VRES the result if V and if
     176       two's complement.  CHECK_BINOP is for most binary operatinos,
     177       CHECK_SBINOP for binary +, -, * when the result type is signed,
     178       and CHECK_UNOP for unary operations.  */
     179    #define CHECK_BINOP(op, opname, a, b, t, v, vres)                       \
     180      VERIFY (INT_##opname##_RANGE_OVERFLOW (a, b, TYPE_MINIMUM (t),        \
     181                                             TYPE_MAXIMUM (t))              \
     182              == (v));                                                      \
     183      VERIFY (INT_##opname##_OVERFLOW (a, b) == (v))
     184    #define CHECK_SBINOP(op, opname, a, b, t, v, vres)                      \
     185      CHECK_BINOP(op, opname, a, b, t, v, vres);                            \
     186      {                                                                     \
     187        t result;                                                           \
     188        ASSERT (INT_##opname##_WRAPV (a, b, &result) == (v));               \
     189        ASSERT (result == ((v) ? (vres) : ((a) op (b))));                   \
     190      }
     191    #define CHECK_UNOP(op, opname, a, t, v)                                 \
     192      VERIFY (INT_##opname##_RANGE_OVERFLOW (a, TYPE_MINIMUM (t),           \
     193                                             TYPE_MAXIMUM (t))              \
     194              == (v));                                                      \
     195      VERIFY (INT_##opname##_OVERFLOW (a) == (v))
     196  
     197    /* INT_<op>_RANGE_OVERFLOW, INT_<op>_OVERFLOW.  */
     198    VERIFY (INT_ADD_RANGE_OVERFLOW (INT_MAX, 1, INT_MIN, INT_MAX));
     199    VERIFY (INT_ADD_OVERFLOW (INT_MAX, 1));
     200  
     201    CHECK_SBINOP (+, ADD, INT_MAX, 1, int, true, INT_MIN);
     202    CHECK_SBINOP (+, ADD, INT_MAX, -1, int, false, INT_MAX - 1);
     203    CHECK_SBINOP (+, ADD, INT_MIN, 1, int, false, INT_MIN + 1);
     204    CHECK_SBINOP (+, ADD, INT_MIN, -1, int, true, INT_MAX);
     205    CHECK_BINOP (+, ADD, UINT_MAX, 1u, unsigned int, true, 0u);
     206    CHECK_BINOP (+, ADD, 0u, 1u, unsigned int, false, 1u);
     207  
     208    CHECK_SBINOP (-, SUBTRACT, INT_MAX, 1, int, false, INT_MAX - 1);
     209    CHECK_SBINOP (-, SUBTRACT, INT_MAX, -1, int, true, INT_MIN);
     210    CHECK_SBINOP (-, SUBTRACT, INT_MIN, 1, int, true, INT_MAX);
     211    CHECK_SBINOP (-, SUBTRACT, INT_MIN, -1, int, false, INT_MIN - -1);
     212    CHECK_BINOP (-, SUBTRACT, UINT_MAX, 1u, unsigned int, false, UINT_MAX - 1u);
     213    CHECK_BINOP (-, SUBTRACT, 0u, 1u, unsigned int, true, 0u - 1u);
     214  
     215    CHECK_UNOP (-, NEGATE, INT_MIN, int, true);
     216    CHECK_UNOP (-, NEGATE, 0, int, false);
     217    CHECK_UNOP (-, NEGATE, INT_MAX, int, false);
     218    CHECK_UNOP (-, NEGATE, 0u, unsigned int, false);
     219    CHECK_UNOP (-, NEGATE, 1u, unsigned int, true);
     220    CHECK_UNOP (-, NEGATE, UINT_MAX, unsigned int, true);
     221  
     222    CHECK_SBINOP (*, MULTIPLY, INT_MAX, INT_MAX, int, true, 1);
     223    CHECK_SBINOP (*, MULTIPLY, INT_MAX, INT_MIN, int, true, INT_MIN);
     224    CHECK_SBINOP (*, MULTIPLY, INT_MIN, INT_MAX, int, true, INT_MIN);
     225    CHECK_SBINOP (*, MULTIPLY, INT_MIN, INT_MIN, int, true, 0);
     226    CHECK_SBINOP (*, MULTIPLY, -1, INT_MIN, int,
     227                  INT_NEGATE_OVERFLOW (INT_MIN), INT_MIN);
     228  #if !defined __HP_cc
     229    CHECK_SBINOP (*, MULTIPLY, LONG_MIN / INT_MAX, (long int) INT_MAX,
     230                  long int, false, LONG_MIN - LONG_MIN % INT_MAX);
     231  #endif
     232  
     233    CHECK_BINOP (/, DIVIDE, INT_MIN, -1, int,
     234                 INT_NEGATE_OVERFLOW (INT_MIN), INT_MIN);
     235    CHECK_BINOP (/, DIVIDE, INT_MAX, 1, int, false, INT_MAX);
     236    CHECK_BINOP (/, DIVIDE, (unsigned int) INT_MIN, -1u, unsigned int,
     237                 false, INT_MIN / -1u);
     238  
     239    CHECK_BINOP (%, REMAINDER, INT_MIN, -1, int, INT_NEGATE_OVERFLOW (INT_MIN), 0);
     240    CHECK_BINOP (%, REMAINDER, INT_MAX, 1, int, false, 0);
     241    CHECK_BINOP (%, REMAINDER, (unsigned int) INT_MIN, -1u, unsigned int,
     242                 false, INT_MIN % -1u);
     243  
     244    CHECK_BINOP (<<, LEFT_SHIFT, UINT_MAX, 1, unsigned int, true, UINT_MAX << 1);
     245    CHECK_BINOP (<<, LEFT_SHIFT, UINT_MAX / 2 + 1, 1, unsigned int, true,
     246                 (UINT_MAX / 2 + 1) << 1);
     247    CHECK_BINOP (<<, LEFT_SHIFT, UINT_MAX / 2, 1, unsigned int, false,
     248                 (UINT_MAX / 2) << 1);
     249  
     250    /* INT_<op>_OVERFLOW and INT_<op>_WRAPV with mixed types.  */
     251    #define CHECK_SUM(a, b, t, v, vres)                                     \
     252      CHECK_SUM1 (a, b, t, v, vres);                                        \
     253      CHECK_SUM1 (b, a, t, v, vres)
     254    #define CHECK_SUM_WRAPV(a, b, t, v, vres, okres)                        \
     255      CHECK_SUM_WRAPV1 (a, b, t, v, vres, okres);                           \
     256      CHECK_SUM_WRAPV1 (b, a, t, v, vres, okres)
     257    #define CHECK_SUM1(a, b, t, v, vres)                                    \
     258      VERIFY (INT_ADD_OVERFLOW (a, b) == (v));                              \
     259      CHECK_SUM_WRAPV1 (a, b, t, v, vres, (a) + (b))
     260    #define CHECK_SUM_WRAPV1(a, b, t, v, vres, okres)                       \
     261      {                                                                     \
     262        t result;                                                           \
     263        ASSERT (INT_ADD_WRAPV (a, b, &result) == (v));                      \
     264        ASSERT (result == ((v) ? (vres) : (okres)));                        \
     265      }
     266    CHECK_SUM (-1, LONG_MIN, long int, true, LONG_MAX);
     267    CHECK_SUM (-1, UINT_MAX, unsigned int, false, DONTCARE);
     268    CHECK_SUM (-1L, INT_MIN, long int, INT_MIN == LONG_MIN,
     269                INT_MIN == LONG_MIN ? INT_MAX : DONTCARE);
     270    CHECK_SUM (0u, -1, unsigned int, true, 0u + -1);
     271    CHECK_SUM (0u, 0, unsigned int, false, DONTCARE);
     272    CHECK_SUM (0u, 1, unsigned int, false, DONTCARE);
     273    CHECK_SUM (1, LONG_MAX, long int, true, LONG_MIN);
     274    CHECK_SUM (1, UINT_MAX, unsigned int, true, 0u);
     275    CHECK_SUM (1L, INT_MAX, long int, INT_MAX == LONG_MAX,
     276                INT_MAX == LONG_MAX ? INT_MIN : DONTCARE);
     277    CHECK_SUM (1u, INT_MAX, unsigned int, INT_MAX == UINT_MAX, 1u + INT_MAX);
     278    CHECK_SUM (1u, INT_MIN, unsigned int, true, 1u + INT_MIN);
     279    CHECK_SUM_WRAPV (-1, 1u, int, false, DONTCARE, 0);
     280    CHECK_SUM_WRAPV (-1, 1ul, int, false, DONTCARE, 0);
     281    CHECK_SUM_WRAPV (-1l, 1u, int, false, DONTCARE, 0);
     282    CHECK_SUM_WRAPV (-100, 1000u, int, false, DONTCARE, 900);
     283    CHECK_SUM_WRAPV (INT_MIN, UINT_MAX, int, false, DONTCARE, INT_MAX);
     284    CHECK_SUM_WRAPV (1u, INT_MAX, int, true, INT_MIN, DONTCARE);
     285    CHECK_SUM_WRAPV (INT_MAX, 1, long int, LONG_MAX <= INT_MAX, INT_MIN,
     286                     INT_MAX + 1L);
     287    CHECK_SUM_WRAPV (UINT_MAX, 1, long int, LONG_MAX <= UINT_MAX, 0,
     288                     UINT_MAX + 1L);
     289    CHECK_SUM_WRAPV (INT_MAX, 1, unsigned long int, ULONG_MAX <= INT_MAX, 0,
     290                     INT_MAX + 1uL);
     291    CHECK_SUM_WRAPV (UINT_MAX, 1, unsigned long int, ULONG_MAX <= UINT_MAX, 0,
     292                     UINT_MAX + 1uL);
     293  
     294    {
     295      long int result;
     296      ASSERT (INT_ADD_WRAPV (1, INT_MAX, &result) == (INT_MAX == LONG_MAX));
     297      ASSERT (INT_ADD_WRAPV (-1, INT_MIN, &result) == (INT_MIN == LONG_MIN));
     298    }
     299  
     300    #define CHECK_DIFFERENCE(a, b, t, v, vres)                              \
     301      VERIFY (INT_SUBTRACT_OVERFLOW (a, b) == (v))
     302    #define CHECK_SDIFFERENCE(a, b, t, v, vres)                             \
     303      CHECK_DIFFERENCE (a, b, t, v, vres);                                  \
     304      CHECK_SDIFFERENCE_WRAPV (a, b, t, v, vres)
     305    #define CHECK_SDIFFERENCE_WRAPV(a, b, t, v, vres)                       \
     306      {                                                                     \
     307        t result;                                                           \
     308        ASSERT (INT_SUBTRACT_WRAPV (a, b, &result) == (v));                 \
     309        ASSERT (result == ((v) ? (vres) : ((a) - (b))));                    \
     310      }
     311    CHECK_DIFFERENCE (INT_MAX, 1u, unsigned int, UINT_MAX < INT_MAX - 1,
     312                      INT_MAX - 1u);
     313    CHECK_DIFFERENCE (UINT_MAX, 1, unsigned int, false, UINT_MAX - 1);
     314    CHECK_DIFFERENCE (0u, -1, unsigned int, false, 0u - -1);
     315    CHECK_DIFFERENCE (UINT_MAX, -1, unsigned int, true, UINT_MAX - -1);
     316    CHECK_DIFFERENCE (INT_MIN, 1u, unsigned int, true, INT_MIN - 1u);
     317    CHECK_DIFFERENCE (-1, 0u, unsigned int, true, -1 - 0u);
     318    CHECK_SDIFFERENCE (-1, INT_MIN, int, false, -1 - INT_MIN);
     319    CHECK_SDIFFERENCE (-1, INT_MAX, int, false, -1 - INT_MAX);
     320    CHECK_SDIFFERENCE (0, INT_MIN, int, INT_MIN < -INT_MAX, INT_MIN);
     321    CHECK_SDIFFERENCE (0, INT_MAX, int, false, 0 - INT_MAX);
     322    CHECK_SDIFFERENCE_WRAPV (-1, 1u, int, false, DONTCARE);
     323    CHECK_SDIFFERENCE_WRAPV (-1, 1ul, int, false, DONTCARE);
     324    CHECK_SDIFFERENCE_WRAPV (-1l, 1u, int, false, DONTCARE);
     325    CHECK_SDIFFERENCE_WRAPV (0u, INT_MAX, int, false, DONTCARE);
     326    CHECK_SDIFFERENCE_WRAPV (1u, INT_MIN, int, true, 1u - INT_MIN);
     327    {
     328      long int result;
     329      ASSERT (INT_SUBTRACT_WRAPV (INT_MAX, -1, &result) == (INT_MAX == LONG_MAX));
     330      ASSERT (INT_SUBTRACT_WRAPV (INT_MIN, 1, &result) == (INT_MAX == LONG_MAX));
     331    }
     332  
     333    #define CHECK_PRODUCT(a, b, t, v, vres)                                 \
     334      CHECK_PRODUCT1 (a, b, t, v, vres);                                    \
     335      CHECK_PRODUCT1 (b, a, t, v, vres)
     336    #define CHECK_SPRODUCT(a, b, t, v, vres)                                \
     337      CHECK_SPRODUCT1 (a, b, t, v, vres);                                   \
     338      CHECK_SPRODUCT1 (b, a, t, v, vres)
     339    #define CHECK_SPRODUCT_WRAPV(a, b, t, v, vres)                          \
     340      CHECK_SPRODUCT_WRAPV1 (a, b, t, v, vres);                             \
     341      CHECK_SPRODUCT_WRAPV1 (b, a, t, v, vres)
     342    #define CHECK_PRODUCT1(a, b, t, v, vres)                                \
     343      VERIFY (INT_MULTIPLY_OVERFLOW (a, b) == (v))
     344    #define CHECK_SPRODUCT1(a, b, t, v, vres)                               \
     345      CHECK_PRODUCT1 (a, b, t, v, vres);                                    \
     346      CHECK_SPRODUCT_WRAPV1 (a, b, t, v, vres)
     347    #define CHECK_SPRODUCT_WRAPV1(a, b, t, v, vres)                         \
     348      {                                                                     \
     349        t result;                                                           \
     350        ASSERT (INT_MULTIPLY_WRAPV (a, b, &result) == (v));                 \
     351        ASSERT (result == ((v) ? (vres) : ((a) * (b))));                    \
     352      }
     353    CHECK_PRODUCT (-1, 1u, unsigned int, true, -1 * 1u);
     354    CHECK_SPRODUCT (-1, INT_MIN, int, INT_NEGATE_OVERFLOW (INT_MIN), INT_MIN);
     355    CHECK_PRODUCT (-1, UINT_MAX, unsigned int, true, -1 * UINT_MAX);
     356    CHECK_SPRODUCT (-32768, LONG_MAX / -32768 - 1, long int, true, LONG_MIN);
     357    CHECK_SPRODUCT (-12345, LONG_MAX / -12345, long int, false, DONTCARE);
     358    CHECK_SPRODUCT (0, -1, int, false, DONTCARE);
     359    CHECK_SPRODUCT (0, 0, int, false, DONTCARE);
     360    CHECK_PRODUCT (0, 0u, unsigned int, false, DONTCARE);
     361    CHECK_SPRODUCT (0, 1, int, false, DONTCARE);
     362    CHECK_SPRODUCT (0, INT_MAX, int, false, DONTCARE);
     363    CHECK_SPRODUCT (0, INT_MIN, int, false, DONTCARE);
     364    CHECK_PRODUCT (0, UINT_MAX, unsigned int, false, DONTCARE);
     365    CHECK_PRODUCT (0u, -1, unsigned int, false, DONTCARE);
     366    CHECK_PRODUCT (0u, 0, unsigned int, false, DONTCARE);
     367    CHECK_PRODUCT (0u, 0u, unsigned int, false, DONTCARE);
     368    CHECK_PRODUCT (0u, 1, unsigned int, false, DONTCARE);
     369    CHECK_PRODUCT (0u, INT_MAX, unsigned int, false, DONTCARE);
     370    CHECK_PRODUCT (0u, INT_MIN, unsigned int, false, DONTCARE);
     371    CHECK_PRODUCT (0u, UINT_MAX, unsigned int, false, DONTCARE);
     372    CHECK_SPRODUCT (1, INT_MAX, int, false, DONTCARE);
     373    CHECK_SPRODUCT (1, INT_MIN, int, false, DONTCARE);
     374    CHECK_PRODUCT (1, UINT_MAX, unsigned int, false, DONTCARE);
     375    CHECK_PRODUCT (1u, INT_MIN, unsigned int, true, 1u * INT_MIN);
     376    CHECK_PRODUCT (1u, INT_MAX, unsigned int, UINT_MAX < INT_MAX, 1u * INT_MAX);
     377    CHECK_PRODUCT (INT_MAX, UINT_MAX, unsigned int, true, INT_MAX * UINT_MAX);
     378    CHECK_PRODUCT (INT_MAX, ULONG_MAX, unsigned long int, true,
     379                   INT_MAX * ULONG_MAX);
     380  #if !defined __HP_cc
     381    CHECK_SPRODUCT (INT_MIN, LONG_MAX / INT_MIN - 1, long int, true, LONG_MIN);
     382    CHECK_SPRODUCT (INT_MIN, LONG_MAX / INT_MIN, long int, false, DONTCARE);
     383  #endif
     384    CHECK_PRODUCT (INT_MIN, UINT_MAX, unsigned int, true, INT_MIN * UINT_MAX);
     385    CHECK_PRODUCT (INT_MIN, ULONG_MAX, unsigned long int, true,
     386                   INT_MIN * ULONG_MAX);
     387    CHECK_SPRODUCT_WRAPV (-1, INT_MAX + 1u, int, false, DONTCARE);
     388    CHECK_SPRODUCT_WRAPV (-1, 1u, int, false, DONTCARE);
     389    CHECK_SPRODUCT (0, ULONG_MAX, int, false, DONTCARE);
     390    CHECK_SPRODUCT (0u, LONG_MIN, int, false, DONTCARE);
     391    {
     392      long int result;
     393      ASSERT (INT_MULTIPLY_WRAPV (INT_MAX, INT_MAX, &result)
     394              == (LONG_MAX / INT_MAX < INT_MAX));
     395      ASSERT (INT_MULTIPLY_WRAPV (INT_MAX, INT_MAX, &result)
     396              || result == INT_MAX * (long int) INT_MAX);
     397      ASSERT (INT_MULTIPLY_WRAPV (INT_MIN, INT_MIN, &result)
     398              || result == INT_MIN * (long int) INT_MIN);
     399    }
     400  
     401  # ifdef LLONG_MAX
     402    {
     403      long long int result;
     404      ASSERT (INT_MULTIPLY_WRAPV (LONG_MAX, LONG_MAX, &result)
     405              == (LLONG_MAX / LONG_MAX < LONG_MAX));
     406      ASSERT (INT_MULTIPLY_WRAPV (LONG_MAX, LONG_MAX, &result)
     407              || result == LONG_MAX * (long long int) LONG_MAX);
     408      ASSERT (INT_MULTIPLY_WRAPV (LONG_MIN, LONG_MIN, &result)
     409              || result == LONG_MIN * (long long int) LONG_MIN);
     410    }
     411  # endif
     412  
     413    /* Check for GCC bug 91450.  */
     414    {
     415      unsigned long long result;
     416      ASSERT (INT_MULTIPLY_WRAPV (int_minus_2, int_1, &result) && result == -2);
     417    }
     418  
     419    #define CHECK_QUOTIENT(a, b, v) VERIFY (INT_DIVIDE_OVERFLOW (a, b) == (v))
     420  
     421    CHECK_QUOTIENT (INT_MIN, -1L, INT_MIN == LONG_MIN);
     422    CHECK_QUOTIENT (INT_MIN, UINT_MAX, false);
     423    CHECK_QUOTIENT (INTMAX_MIN, UINTMAX_MAX, false);
     424    CHECK_QUOTIENT (INTMAX_MIN, UINT_MAX, false);
     425    CHECK_QUOTIENT (-11, 10u, true);
     426    CHECK_QUOTIENT (-10, 10u, true);
     427    CHECK_QUOTIENT (-9, 10u, false);
     428    CHECK_QUOTIENT (11u, -10, true);
     429    CHECK_QUOTIENT (10u, -10, true);
     430    CHECK_QUOTIENT (9u, -10, false);
     431  
     432    #define CHECK_REMAINDER(a, b, v) VERIFY (INT_REMAINDER_OVERFLOW (a, b) == (v))
     433  
     434    CHECK_REMAINDER (INT_MIN, -1L, INT_MIN == LONG_MIN);
     435    CHECK_REMAINDER (-1, UINT_MAX, true);
     436    CHECK_REMAINDER ((intmax_t) -1, UINTMAX_MAX, true);
     437    CHECK_REMAINDER (INTMAX_MIN, UINT_MAX,
     438                     (INTMAX_MAX < UINT_MAX
     439                      && - (unsigned int) INTMAX_MIN % UINT_MAX != 0));
     440    CHECK_REMAINDER (INT_MIN, ULONG_MAX, INT_MIN % ULONG_MAX != 1);
     441    CHECK_REMAINDER (1u, -1, false);
     442    CHECK_REMAINDER (37*39u, -39, false);
     443    CHECK_REMAINDER (37*39u + 1, -39, true);
     444    CHECK_REMAINDER (37*39u - 1, -39, true);
     445    CHECK_REMAINDER (LONG_MAX, -INT_MAX, false);
     446  
     447    return 0;
     448  }