Re: svn commit: r227369 - head/bin/sh

2011-11-23 Thread Bruce Evans

On Tue, 22 Nov 2011, Jilles Tjoelker wrote:


On Mon, Nov 21, 2011 at 06:29:06PM +1100, Bruce Evans wrote:

On Wed, 9 Nov 2011, Jilles Tjoelker wrote:

On Wed, Nov 09, 2011 at 09:35:51AM +0100, Stefan Farfeleder wrote:

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:

...



The possibility of a signal is mentioned in C99TC2 draft n1124 and
remains in C1x draft n1548. The documentation in 'info gcc' is
consistent with that.


I wonder why they (C standards) broke that.  Though the implementation
may prefer to raising a signal, C90 (and C99-non-draft?) doesn't allow
that, and it is a large change to allow one.


]   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.


That would be a non-practical implementation, as it would be both slower
and run fewer existing applications.


It's point is to run fewer existing applications -- the broken ones :-).

This would not necessarily be slower.  The hardware might want to or
be able to trap (at no cost unless there is overflow).  Then the
implementation can convert the trap to a random result, instead of
rasing a signal.  The hardware might be 1's complement, but not
trap.  Then the fast version would give a non-random result, but not
what you want.  The slow version to give the 2's complement result
that you want could probably give a random result instead.  Now it
is apparently allowed to trap instead.  A trap is of course better
for running fewer existing applications.  Old ones won't have a trap
handler and will just crash.


I think there should be some loopholes to do signed integer arithmetic
with wraparound, not allowing the compiler to assume there is no
overflow.


Something like FENV_ACCESS pragmas would be useful.  But these are still
not supported by gcc-4.2 or clang.


While POSIX leaves the behaviour on overflow and division by zero in
shell arithmetic undefined as with C arithmetic (although it mentions
the possibility of converting to floating point in case of overflow), I
prefer that sh(1) not crash.


It should avoid overflow and produce its own implementation-defined result,
without depending on implementation-defined or undefined behaviour in C.
This is easier when someone else is doing it :-).

Bruce
___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to svn-src-head-unsubscr...@freebsd.org


Re: svn commit: r227369 - head/bin/sh

2011-11-21 Thread Jilles Tjoelker
On Mon, Nov 21, 2011 at 06:29:06PM +1100, Bruce Evans wrote:
 On Wed, 9 Nov 2011, Jilles Tjoelker wrote:
  On Wed, Nov 09, 2011 at 09:35:51AM +0100, Stefan Farfeleder wrote:
  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.

The possibility of a signal is mentioned in C99TC2 draft n1124 and
remains in C1x draft n1548. The documentation in 'info gcc' is
consistent with that.

  ]   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.

That would be a non-practical implementation, as it would be both slower
and run fewer existing applications.

I think there should be some loopholes to do signed integer arithmetic
with wraparound, not allowing the compiler to assume there is no
overflow.

While POSIX leaves the behaviour on overflow and division by zero in
shell arithmetic undefined as with C arithmetic (although it mentions
the possibility of converting to floating point in case of overflow), I
prefer that sh(1) not crash.

-- 
Jilles Tjoelker
___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to svn-src-head-unsubscr...@freebsd.org


Re: svn commit: r227369 - head/bin/sh

2011-11-20 Thread Bruce Evans

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 +, 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.cTue Nov  8 23:44:26 2011(r227368)
+++ head/bin/sh/arith_yacc.cTue 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
___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to svn-src-head-unsubscr...@freebsd.org


Re: svn commit: r227369 - head/bin/sh

2011-11-09 Thread Stefan Farfeleder
On Tue, Nov 08, 2011 at 11:54:39PM +, 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?

Stefan
___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to svn-src-head-unsubscr...@freebsd.org


Re: svn commit: r227369 - head/bin/sh

2011-11-09 Thread Jilles Tjoelker
On Wed, Nov 09, 2011 at 09:35:51AM +0100, Stefan Farfeleder wrote:
 On Tue, Nov 08, 2011 at 11:54:39PM +, 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.cTue Nov  8 23:44:26 2011
  (r227368)
  +++ head/bin/sh/arith_yacc.cTue 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.

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).'

]   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.

-- 
Jilles Tjoelker
___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to svn-src-head-unsubscr...@freebsd.org


svn commit: r227369 - head/bin/sh

2011-11-08 Thread Jilles Tjoelker
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.cTue Nov  8 23:44:26 2011(r227368)
+++ head/bin/sh/arith_yacc.cTue 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:
___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to svn-src-head-unsubscr...@freebsd.org