[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: proposed new module intprops-test
From: |
Bruno Haible |
Subject: |
Re: proposed new module intprops-test |
Date: |
Thu, 19 May 2011 15:07:35 +0200 |
User-agent: |
KMail/1.9.9 |
Hi Paul,
> 2011-05-19 Paul Eggert <address@hidden>
>
> + intprops: work around C compiler bugs
> + * lib/intprops.h (INT_MULTIPLY_RANGE_OVERFLOW): Work around compiler
> + bug in Sun C 5.11 2010/08/13 and other compilers; see
> + <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00401.html>.
Thanks, this patch fixed the errors on OSF/1 5.1 and reduced the errors on
Solaris 9 to only one:
cc -O -DHAVE_CONFIG_H -I. -DGNULIB_STRICT_CHECKING=1 -I. -I. -I.. -I./.. -I.
./gllib -I./../gllib -g -c test-intprops.c
"test-intprops.c", line 40: non-constant bit-field size
"test-intprops.c", line 40: bit-field size < 0: _gl_verify_error_if_negative
cc: acomp failed for test-intprops.c
*** Error code 2
It has no effect on HP-UX and IRIX. So that bug with && and || is specific
to OSF/1 and Solaris.
> From e9d47071a68819604a698a9ad5f188472e1c3792 Mon Sep 17 00:00:00 2001
> From: Paul Eggert <address@hidden>
> Date: Thu, 19 May 2011 01:43:17 -0700
> Subject: [PATCH 3/3] intprop-tests: port to older and more-pedantic compilers
>
> * modules/intprops-tests (Files): Add tests/macros.h.
> * tests/test-intprops.c: Include macros.h.
> (TYPE_IS_INTEGER): Use ASSERT, not verify, to test this macro, as
> it's no longer documented to expand to an integer constant expression.
> (TYPE_SIGNED): Use ASSERT, not verify, to test this macro when the
> argument is floating point, as it's no longer documented to expand
> to an integer constant expression in that case.
This part of the patch fixed the build on Solaris 9.
> (UINT_MAX, ULONG_MAX, UINTMAX_MAX): Redefine to work around
> compiler bugs reported by Bruno Haible. See
> <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00401.html>.
> (U0, U1): New constants, to work around the same bugs. Also,
> in tests, use e.g., "(unsigned int) 39" rather than "39u".
This part of the patch has no effect on HP-UX, IRIX, and neither on
OSF/1 and Solaris where the test already compiles fine. You could just as
well revert it.
Analysis of the HP-UX cc bug: Here are successive simplifications of the
expressions. I annotated them with the "cc -c" result.
===============================================================================
#include <config.h>
#include "intprops.h"
#include "verify.h"
#include <stdbool.h>
#include <inttypes.h>
#define check_binop(op, a, b, min, max, overflow) \
(INT_##op##_RANGE_OVERFLOW (a, b, min, max) == (overflow) \
&& INT_##op##_OVERFLOW (a, b) == (overflow))
/* Error */
verify (check_binop (ADD, UINT_MAX, 1u, 0u, UINT_MAX, true));
/* Error */
verify (INT_ADD_RANGE_OVERFLOW (UINT_MAX, 1u, 0u, UINT_MAX) == true &&
INT_ADD_OVERFLOW (UINT_MAX, 1u) == true);
/* OK */
verify (INT_ADD_RANGE_OVERFLOW (UINT_MAX, 1u, 0u, UINT_MAX) == true);
/* Error */
verify (INT_ADD_OVERFLOW (UINT_MAX, 1u) == true);
/* Error */
verify (_GL_BINARY_OP_OVERFLOW (UINT_MAX, 1u, _GL_ADD_OVERFLOW) == true);
/* Error */
verify (_GL_ADD_OVERFLOW (UINT_MAX, 1u, _GL_INT_MINIMUM (UINT_MAX | 1u),
_GL_INT_MAXIMUM (UINT_MAX | 1u)) == true);
/* Error */
verify ((_GL_INT_MINIMUM (UINT_MAX | 1u) < 0 ? INT_ADD_RANGE_OVERFLOW
(UINT_MAX, 1u, _GL_INT_MINIMUM (UINT_MAX | 1u), _GL_INT_MAXIMUM (UINT_MAX |
1u)) : UINT_MAX < 0 ? 1u <= UINT_MAX + 1u : 1u < 0 ? UINT_MAX <= UINT_MAX + 1u
: UINT_MAX + 1u < 1u) == true);
/* Error */
verify (_GL_INT_MINIMUM (UINT_MAX | 1u) < 0 ? INT_ADD_RANGE_OVERFLOW (UINT_MAX,
1u, _GL_INT_MINIMUM (UINT_MAX | 1u), _GL_INT_MAXIMUM (UINT_MAX | 1u)) :
UINT_MAX < 0 ? 1u <= UINT_MAX + 1u : 1u < 0 ? UINT_MAX <= UINT_MAX + 1u :
UINT_MAX + 1u < 1u);
/* OK */
verify (UINT_MAX < 0 ? 1u <= UINT_MAX + 1u : 1u < 0 ? UINT_MAX <= UINT_MAX + 1u
: UINT_MAX + 1u < 1u);
/* Error */
verify (_GL_INT_MINIMUM (UINT_MAX | 1u) >= 0);
/* Error */
verify (INT_ADD_RANGE_OVERFLOW (UINT_MAX, 1u, _GL_INT_MINIMUM (UINT_MAX | 1u),
_GL_INT_MAXIMUM (UINT_MAX | 1u)));
/* Error */
verify (!INT_ADD_RANGE_OVERFLOW (UINT_MAX, 1u, _GL_INT_MINIMUM (UINT_MAX | 1u),
_GL_INT_MAXIMUM (UINT_MAX | 1u)));
/* Error */
verify (_GL_INT_MINIMUM (UINT_MAX) >= 0);
/* Error */
verify (_GL_INT_MINIMUM (1u) >= 0);
/* Error */
verify (!_GL_INT_SIGNED (1u));
/* Error */
verify (_GL_INT_CONVERT (1u, 0) >= 0);
/* Error */
verify (1u - 1u + 0 >= 0);
/* Error */
verify (1u - 1u >= 0);
/* Error */
verify (1u + 0 >= 0);
/* OK */
verify (1u >= 0);
===============================================================================
As you can see, plus and minus expressions of which one operand is unsigned are
not understood by this compiler. It yells
"error 1511: Bit-field size must be a constant."
Writing (unsigned int) 1 instead of 1u does not help.
So I think, you will have to use ASSERT here instead of verify.
Analysis of the IRIX cc bug:
===============================================================================
#include <config.h>
#include "intprops.h"
#include "verify.h"
#include <stdbool.h>
#include <inttypes.h>
#define check_binop(op, a, b, min, max, overflow) \
(INT_##op##_RANGE_OVERFLOW (a, b, min, max) == (overflow) \
&& INT_##op##_OVERFLOW (a, b) == (overflow))
/* Error */
verify (check_binop (ADD, UINT_MAX, 1u, 0u, UINT_MAX, true));
/* Error */
verify (INT_ADD_RANGE_OVERFLOW (UINT_MAX, 1u, 0u, UINT_MAX) == true &&
INT_ADD_OVERFLOW (UINT_MAX, 1u) == true);
/* OK */
verify (INT_ADD_RANGE_OVERFLOW (UINT_MAX, 1u, 0u, UINT_MAX) == true);
/* Error */
verify (INT_ADD_OVERFLOW (UINT_MAX, 1u) == true);
/* Error */
verify (_GL_BINARY_OP_OVERFLOW (UINT_MAX, 1u, _GL_ADD_OVERFLOW) == true);
/* Error */
verify (_GL_ADD_OVERFLOW (UINT_MAX, 1u, _GL_INT_MINIMUM (UINT_MAX | 1u),
_GL_INT_MAXIMUM (UINT_MAX | 1u)) == true);
/* Error */
verify ((_GL_INT_MINIMUM (UINT_MAX | 1u) < 0 ? INT_ADD_RANGE_OVERFLOW
(UINT_MAX, 1u, _GL_INT_MINIMUM (UINT_MAX | 1u), _GL_INT_MAXIMUM (UINT_MAX |
1u)) : UINT_MAX < 0 ? 1u <= UINT_MAX + 1u : 1u < 0 ? UINT_MAX <= UINT_MAX + 1u
: UINT_MAX + 1u < 1u) == true);
/* Error */
verify (_GL_INT_MINIMUM (UINT_MAX | 1u) < 0 ? INT_ADD_RANGE_OVERFLOW (UINT_MAX,
1u, _GL_INT_MINIMUM (UINT_MAX | 1u), _GL_INT_MAXIMUM (UINT_MAX | 1u)) :
UINT_MAX < 0 ? 1u <= UINT_MAX + 1u : 1u < 0 ? UINT_MAX <= UINT_MAX + 1u :
UINT_MAX + 1u < 1u);
/* OK */
verify (UINT_MAX < 0 ? 1u <= UINT_MAX + 1u : 1u < 0 ? UINT_MAX <= UINT_MAX + 1u
: UINT_MAX + 1u < 1u);
/* OK */
verify (_GL_INT_MINIMUM (UINT_MAX | 1u) >= 0);
/* Error */
verify (INT_ADD_RANGE_OVERFLOW (UINT_MAX, 1u, _GL_INT_MINIMUM (UINT_MAX | 1u),
_GL_INT_MAXIMUM (UINT_MAX | 1u)));
/* Error */
verify (!INT_ADD_RANGE_OVERFLOW (UINT_MAX, 1u, _GL_INT_MINIMUM (UINT_MAX | 1u),
_GL_INT_MAXIMUM (UINT_MAX | 1u)));
/* Error */
verify (1u < 0 ? UINT_MAX < _GL_INT_MINIMUM (UINT_MAX | 1u) - 1u :
_GL_INT_MAXIMUM (UINT_MAX | 1u) - 1u < UINT_MAX);
/* OK */
verify (_GL_INT_MAXIMUM (UINT_MAX | 1u) - 1u < UINT_MAX);
/* Error */
verify (0 ? UINT_MAX < _GL_INT_MINIMUM (UINT_MAX | 1u) - 1u : 1);
/* Error */
verify (0 ? _GL_INT_MINIMUM (UINT_MAX | 1u) >= 0 : 1);
/* Error */
verify (0 ? _GL_INT_MINIMUM (1u) >= 0 : 1);
/* Error */
verify (0 ? (_GL_INT_SIGNED (1u) ? - _GL_INT_TWOS_COMPLEMENT (1u) -
_GL_SIGNED_INT_MAXIMUM (1u) : _GL_INT_CONVERT (1u, 0)) : 1);
/* OK */
verify (0 ? _GL_INT_SIGNED (1u) : 1);
/* OK */
verify (!_GL_INT_SIGNED (1u));
verify (0 ? - _GL_INT_TWOS_COMPLEMENT (1u) - _GL_SIGNED_INT_MAXIMUM (1u) : 1);
/* OK */
verify (0 ? _GL_INT_CONVERT (1u, 0) : 1);
/* OK */
verify (!_GL_INT_CONVERT (1u, 0));
/* OK */
verify (0 ? (0 ? - _GL_INT_TWOS_COMPLEMENT (1u) - _GL_SIGNED_INT_MAXIMUM (1u) :
_GL_INT_CONVERT (1u, 0)) : 1);
/* Error */
verify (0 ? (_GL_INT_SIGNED (1u) ? - 1 - _GL_SIGNED_INT_MAXIMUM (1u) :
_GL_INT_CONVERT (1u, 0)) : 1);
/* Error */
verify (0 ? (_GL_INT_SIGNED (1u) ? - 1 - _GL_SIGNED_INT_MAXIMUM (1u) : 0u) : 1);
/* Error */
verify (0 ? (_GL_INT_SIGNED (1u) ? - 1 - 0x7fff : 0u) : 1);
/* OK */
verify (0 ? 0u : 1);
/* Error */
verify (0 ? (1u - 1u + -1 < 0 ? - 1 - 0x7fff : 0u) : 1);
/* Error */
verify (0 ? (0u + -1 < 0 ? - 1 - 0x7fff : 0u) : 1);
/* OK */
verify (0 ? (0u - 1 < 0 ? - 1 - 0x7fff : 0u) : 1);
===============================================================================
So here apparently the problem is adding an unsigned value and -1. The following
change fixes this error for me:
#define _GL_INT_SIGNED(e) (_GL_INT_CONVERT (e, -1) < 0)
#undef _GL_INT_SIGNED
#define _GL_INT_SIGNED(e) ((e) - (e) - 1 < 0)
Other errors still remain; to be investigated in the next round.
Bruno
--
In memoriam Anne Boleyn <http://en.wikipedia.org/wiki/Anne_Boleyn>
- proposed new module intprops-test, Paul Eggert, 2011/05/10
- Re: proposed new module intprops-test, Eric Blake, 2011/05/10
- Re: proposed new module intprops-test, Paul Eggert, 2011/05/10
- Re: proposed new module intprops-test, Bruno Haible, 2011/05/18
- Re: proposed new module intprops-test, Paul Eggert, 2011/05/19
- Re: proposed new module intprops-test,
Bruno Haible <=
- Re: proposed new module intprops-test, Paul Eggert, 2011/05/19
- Re: proposed new module intprops-test, Bruno Haible, 2011/05/20
- Re: proposed new module intprops-test, Paul Eggert, 2011/05/20