svn commit: r227369 - head/bin/sh

Bruce Evans brde at optusnet.com.au
Mon Nov 21 07:29:12 UTC 2011


On Wed, 9 Nov 2011, Jilles Tjoelker wrote:

> On Wed, Nov 09, 2011 at 09:35:51AM +0100, Stefan Farfeleder wrote:
>> On Tue, Nov 08, 2011 at 11:54:39PM +0000, Jilles Tjoelker wrote:
>>> Author: jilles
>>> Date: Tue Nov  8 23:54:39 2011
>>> New Revision: 227369
>>> URL: http://svn.freebsd.org/changeset/base/227369
>
>>> Log:
>>>   sh: Remove undefined behaviour due to overflow in +/-/* in arithmetic.
>
>>>   With i386 base gcc and i386 base clang, arith_yacc.o remains unchanged.
>
>>> Modified:
>>>   head/bin/sh/arith_yacc.c
>
>>> Modified: head/bin/sh/arith_yacc.c
>>> ==============================================================================
>>> --- head/bin/sh/arith_yacc.c	Tue Nov  8 23:44:26 2011	(r227368)
>>> +++ head/bin/sh/arith_yacc.c	Tue Nov  8 23:54:39 2011	(r227369)
>>> @@ -131,11 +131,11 @@ static arith_t do_binop(int op, arith_t
>>>  			yyerror("divide error");
>>>  		return op == ARITH_REM ? a % b : a / b;
>>>  	case ARITH_MUL:
>>> -		return a * b;
>>> +		return (uintmax_t)a * (uintmax_t)b;
>>>  	case ARITH_ADD:
>>> -		return a + b;
>>> +		return (uintmax_t)a + (uintmax_t)b;
>>>  	case ARITH_SUB:
>>> -		return a - b;
>>> +		return (uintmax_t)a - (uintmax_t)b;
>>>  	case ARITH_LSHIFT:
>>>  		return a << b;
>>>  	case ARITH_RSHIFT:
>
>> Isn't the behaviour undefined too when you convert an out-of-range
>> uintmax_t value back into an intmax_t value?
>
> The result is implementation-defined or an implementation-defined signal
> is raised.

C doesn't allow any signal, at least in C90 and n869.txt draft C99:

%        6.3.1.3  Signed and unsigned integers
%        ...
%        [#3] Otherwise, the new type is signed and the value  cannot
%        be  represented in it; the result is implementation-defined.
%        J.3  Implementation-defined behavior
%        ...
%        J.3.5  Integers
% 
%        [#1]
%        ...
%          -- The result of converting an integer to a signed integer
%             type when the value cannot be represented in an  object
%             of that type (6.3.1.3).

n869.txt barely mentions signals, especially here.  Its only literal
match for "signal raised" is in Annex H for LIA, which says that if
an arithmetic exception raises a signal, then the signal shall be
SIGFPE, and this is mainly for floating point.  It has many more literal
matches for "exception raised", since Annex F for IEEE754 requires
exceptions to be raised a lot; these exceptions normally don't generate
signals.

> GCC documentation (gcc.info 4.5 Integers implementation) says this
>
> ] * `The result of, or the signal raised by, converting an integer to a
> ]   signed integer type when the value cannot be represented in an
> ]   object of that type (C90 6.2.1.2, C99 6.3.1.3).'

", or the signal raised by, " in this seems to be a bug in gcc
documentation.  The documentation of implementation-defined behaviour
shouldn't mention that specifed behaviour is implemented, at least
without distinguishing the part that is as specified.

>
> ]   For conversion to a type of width N, the value is reduced modulo
> ]   2^N to be within range of the type; no signal is raised.
>
> which is exactly what we need.

Of course, a correct implementation would give a random result, so that
no one depends on implementation-defined behaviour.

Bruce


More information about the svn-src-head mailing list