plan9port/src/cmd/rc
Xi Wang 1bfec89b99 rc: avoid undefined C
There are two bugs in pdec() on INT_MIN:

* wrong output.

`n = 1-n' should be `n = -1-n' when n is INT_MIN.

* infinite loop.

gcc optimizes `if(n>=0)' into `if(true)' because `-INT_MIN' (signed integer overflow) is undefined behavior in C, and gcc assumes the negation of a negative number must be positive.  The resulting binary keeps printing '-' forever given INT_MIN.

Try the simplified pdec.c below.

$ gcc pdec.c
$ ./a.out -2147483648
--214748364*

$ gcc pdec.c -O2
$ ./a.out -2147483648
<infinite loop>

$ gcc pdec.c -O2 -D__PATCH__
$ ./a.out -2147483648
-2147483648

=== pdec.c ===

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#define io void

void pchr(io *f, int c)
{
        putchar(c);
}

void pdec(io *f, int n)
{
        if(n<0){
#ifndef __PATCH__
                n=-n;
                if(n>=0){
                        pchr(f, '-');
                        pdec(f, n);
                        return;
                }
                /* n is two's complement minimum integer */
                n = 1-n;
#else
                if(n!=INT_MIN){
                        pchr(f, '-');
                        pdec(f, -n);
                        return;
                }
                /* n is two's complement minimum integer */
                n = -(INT_MIN+1);
#endif
                pchr(f, '-');
                pdec(f, n/10);
                pchr(f, n%10+'1');
                return;
        }
        if(n>9)
                pdec(f, n/10);
        pchr(f, n%10+'0');
}

int main(int argc, char **argv)
{
        int n = atoi(argv[1]);
        pdec(NULL, n);
        putchar('\n');
}

R=rsc
CC=plan9port.codebot
https://codereview.appspot.com/7241055
2013-03-19 14:36:50 -04:00
..
.cvsignore
code.c rc: fix local variables in functions 2008-08-14 10:29:29 -04:00
exec.c rc: silence lion roar 2011-08-02 16:21:33 -04:00
exec.h sync with plan 9 2007-03-26 12:02:41 +00:00
fmtquote.c
fns.h fix wait 2007-03-26 14:26:32 +00:00
getflags.c sync with plan 9 2007-03-26 12:02:41 +00:00
getflags.h
glob.c rc: handle 4-byte utf-8 2011-01-02 13:44:15 -05:00
havefork.c rc: fix $ifs bug introduced with utf-8 code 2011-02-16 12:48:06 -05:00
haventfork.c
here.c sync with plan 9 2007-03-26 12:02:41 +00:00
io.c rc: avoid undefined C 2013-03-19 14:36:50 -04:00
io.h sync with plan 9 2007-03-26 12:02:41 +00:00
lex.c rc: handle 4-byte utf-8 2011-01-02 13:44:15 -05:00
mkfile fix wait 2007-03-26 14:26:32 +00:00
pcmd.c sync with plan 9 2007-03-26 12:02:41 +00:00
pfnc.c sync with plan 9 2007-03-26 12:02:41 +00:00
plan9ish.c fix wait 2007-03-26 14:26:32 +00:00
rc.h rc: handle 4-byte utf-8 2011-01-02 13:44:15 -05:00
simple.c rc: fix local variables in functions 2008-08-14 10:29:29 -04:00
subr.c more memory errors (valgrind) 2007-03-26 15:02:15 +00:00
syn.y sync with plan 9 2007-03-26 12:02:41 +00:00
trap.c sync with plan 9 2007-03-26 12:02:41 +00:00
tree.c sync with plan 9 2007-03-26 12:02:41 +00:00
unixcrap.c rc: make read not ignore interrupts/errors (again) 2009-08-23 13:25:44 -04:00
var.c sync with plan 9 2007-03-26 12:02:41 +00:00