Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!ames!ncar!tank!oddjob!mimsy!aplcen!jhunix!ins_adjb From: ins_adjb@jhunix.HCF.JHU.EDU (Daniel Jay Barrett) Newsgroups: comp.sys.amiga.tech Subject: Re: Manx bug Message-ID: <7160@jhunix.HCF.JHU.EDU> Date: 5 Oct 88 12:28:58 GMT References: <220@snll-arpagw.UUCP> <7128@jhunix.HCF.JHU.EDU> <222@snll-arpagw.UUCP> Organization: Johns Hopkins Univ. Computing Ctr. Lines: 680 Several people have asked to see my minimal code example for the Manx assembler bug. Here is a shar file containing lots of information, including the letters I wrote to Manx and (long ago) to the Net. I hope this posting is not too big. Enjoy! It's probably best to read the two "letter" files to understand what the rest of the files here are. Basically, I have enclosed 2 programs called "good" and "bad". "good" compiles and assembles, but "bad" does not. The difference between good.c and bad.c is only 1 character. Enclosed are the 2 C files, the result of running "diff" on the files, the assembler output from the 2 C files, the "diff" of the assembler files, and my letters to Manx and to the Net. Enjoy! Dan Barrett ins_adjb@jhunix.UUCP UUCP barrett@cs.jhu.edu (128.220.13.4) ARPA Dept. of Computer Science, Johns Hopkins University, Baltimore, MD 21218 # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by crabcake!barrett on Wed Oct 5 00:14:11 EDT 1988 # Contents: asm.diffs bad.asm bad.c c.diffs error.message good.asm good.c # letter net.letter echo x - asm.diffs sed 's/^@//' > "asm.diffs" <<'@//E*O*F asm.diffs//' THIS IS THE OUTPUT OF "DIFF BAD.ASM GOOD.ASM" ********************************************* 44c44 < ; case 'x': /* Change 'x' to ANY other character from */ --- > ; case 'y': /* Change 'x' to ANY other character from */ 131a132 > dc.w .29-.31-2 135,138c136,140 < cmp.l #55,d0 < bcc .29 < asl.l #1,d0 < move.w .30(pc,d0.w),d0 --- > cmp.l #56,d0 > bcc .29 > asl.l #1,d0 > lea .30,a0 > move.w (a0,d0.w),d0 @//E*O*F asm.diffs// chmod u=rw,g=r,o=r asm.diffs echo x - bad.asm sed 's/^@//' > "bad.asm" <<'@//E*O*F bad.asm//' ;:ts=8 ;main() ;{ public _main _main: link a5,#.2 movem.l .3,-(sp) ; char p; ; ; p = 'g'; move.b #103,-1(a5) ; ; switch(p) { move.b -1(a5),d0 ext.w d0 ext.l d0 bra .4 ; case 'a': @.6 ; case 'b': @.7 ; case 'c': @.8 ; case 'd': @.9 ; case 'e': @.10 ; case 'f': @.11 ; case 'g': @.12 ; case 'h': @.13 ; case 'i': @.14 ; case 'j': @.15 ; case 'k': @.16 ; case 'l': @.17 ; case 'm': @.18 ; case 'x': /* Change 'x' to ANY other character from */ @.19 ; /* 'n' to 'z', or possibly others, and this */ ; /* compiles and assembles without error. */ ; case 'B': @.20 ; case 'D': @.21 ; case 'F': @.22 ; case 'H': @.23 ; case 'I': @.24 ; case 'L': @.25 ; case 'O': @.26 ; case 'P': @.27 ; case 'X': @.28 ; break; bra .5 ; default: @.29 ; puts("foo"); pea .1+0 jsr _puts add.w #4,sp ; break; bra .5 ; } @.30 dc.w .20-.31-2 dc.w .29-.31-2 dc.w .21-.31-2 dc.w .29-.31-2 dc.w .22-.31-2 dc.w .29-.31-2 dc.w .23-.31-2 dc.w .24-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .25-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .26-.31-2 dc.w .27-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .28-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .6-.31-2 dc.w .7-.31-2 dc.w .8-.31-2 dc.w .9-.31-2 dc.w .10-.31-2 dc.w .11-.31-2 dc.w .12-.31-2 dc.w .13-.31-2 dc.w .14-.31-2 dc.w .15-.31-2 dc.w .16-.31-2 dc.w .17-.31-2 dc.w .18-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .19-.31-2 @.4 sub.l #66,d0 cmp.l #55,d0 bcc .29 asl.l #1,d0 move.w .30(pc,d0.w),d0 @.31 jmp (pc,d0.w) @.5 ;} @.32 movem.l (sp)+,.3 unlk a5 rts @.2 equ -2 @.3 reg @.1 dc.b 102,111,111,0 ds 0 public _puts public .begin dseg end @//E*O*F bad.asm// chmod u=rw,g=r,o=r bad.asm echo x - bad.c sed 's/^@//' > "bad.c" <<'@//E*O*F bad.c//' main() { char p; p = 'g'; switch(p) { case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'x': /* Change 'x' to ANY other character from */ /* 'n' to 'z', or possibly others, and this */ /* compiles and assembles without error. */ case 'B': case 'D': case 'F': case 'H': case 'I': case 'L': case 'O': case 'P': case 'X': break; default: puts("foo"); break; } } @//E*O*F bad.c// chmod u=rw,g=r,o=r bad.c echo x - c.diffs sed 's/^@//' > "c.diffs" <<'@//E*O*F c.diffs//' THIS IS THE OUTPUT OF "DIFF BAD.C GOOD.C". ****************************************** 21c21 < case 'x': /* Change 'x' to ANY other character from */ --- > case 'y': /* Change 'x' to ANY other character from */ @//E*O*F c.diffs// chmod u=rw,g=r,o=r c.diffs echo x - error.message sed 's/^@//' > "error.message" <<'@//E*O*F error.message//' move.w .41(pc,d0.w),d0 ^ ram:ctmpA21.056: 784: ***ERROR - Pc relative out of byte range, -130. 1 errors @//E*O*F error.message// chmod u=rw,g=r,o=r error.message echo x - good.asm sed 's/^@//' > "good.asm" <<'@//E*O*F good.asm//' ;:ts=8 ;main() ;{ public _main _main: link a5,#.2 movem.l .3,-(sp) ; char p; ; ; p = 'g'; move.b #103,-1(a5) ; ; switch(p) { move.b -1(a5),d0 ext.w d0 ext.l d0 bra .4 ; case 'a': @.6 ; case 'b': @.7 ; case 'c': @.8 ; case 'd': @.9 ; case 'e': @.10 ; case 'f': @.11 ; case 'g': @.12 ; case 'h': @.13 ; case 'i': @.14 ; case 'j': @.15 ; case 'k': @.16 ; case 'l': @.17 ; case 'm': @.18 ; case 'y': /* Change 'x' to ANY other character from */ @.19 ; /* 'n' to 'z', or possibly others, and this */ ; /* compiles and assembles without error. */ ; case 'B': @.20 ; case 'D': @.21 ; case 'F': @.22 ; case 'H': @.23 ; case 'I': @.24 ; case 'L': @.25 ; case 'O': @.26 ; case 'P': @.27 ; case 'X': @.28 ; break; bra .5 ; default: @.29 ; puts("foo"); pea .1+0 jsr _puts add.w #4,sp ; break; bra .5 ; } @.30 dc.w .20-.31-2 dc.w .29-.31-2 dc.w .21-.31-2 dc.w .29-.31-2 dc.w .22-.31-2 dc.w .29-.31-2 dc.w .23-.31-2 dc.w .24-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .25-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .26-.31-2 dc.w .27-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .28-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .6-.31-2 dc.w .7-.31-2 dc.w .8-.31-2 dc.w .9-.31-2 dc.w .10-.31-2 dc.w .11-.31-2 dc.w .12-.31-2 dc.w .13-.31-2 dc.w .14-.31-2 dc.w .15-.31-2 dc.w .16-.31-2 dc.w .17-.31-2 dc.w .18-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .29-.31-2 dc.w .19-.31-2 @.4 sub.l #66,d0 cmp.l #56,d0 bcc .29 asl.l #1,d0 lea .30,a0 move.w (a0,d0.w),d0 @.31 jmp (pc,d0.w) @.5 ;} @.32 movem.l (sp)+,.3 unlk a5 rts @.2 equ -2 @.3 reg @.1 dc.b 102,111,111,0 ds 0 public _puts public .begin dseg end @//E*O*F good.asm// chmod u=rw,g=r,o=r good.asm echo x - good.c sed 's/^@//' > "good.c" <<'@//E*O*F good.c//' main() { char p; p = 'g'; switch(p) { case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'y': /* Change 'x' to ANY other character from */ /* 'n' to 'z', or possibly others, and this */ /* compiles and assembles without error. */ case 'B': case 'D': case 'F': case 'H': case 'I': case 'L': case 'O': case 'P': case 'X': break; default: puts("foo"); break; } } @//E*O*F good.c// chmod u=rw,g=r,o=r good.c echo x - letter sed 's/^@//' > "letter" <<'@//E*O*F letter//' @.ps 11 @.vs 12 @.sp 5 @.TS expand center; lp+3 rp-1 lp-1 rp-1. \fBDANIEL J. BARRETT\fR Home: (301) 889-3934 Computer Science Department, Johns Hopkins University, Baltimore, MD 21218 Work: (301) 338-7784 _ @.TE @.ce 1 \fI\n(mo/\n(dy/\n(yr\fR @.ps 12 @.vs 13 @.ad b @.nh @.nf Manx Technical Support \fIAttn: Dorothy\fR @.fi Dear Tech Support: I have discovered a very strange bug in your Amiga C compiler, versions 3.4 and 3.6A. This is 100% definitely a compiler bug and not a user error. I discussed this bug on 3/1/88 with a very helpful tech person named Dorothy. I have now isolated the bug and herein provide a simple program that generates it. In the pages that follow, I have documented the bug extensively. The program \fBbad.c\fR demonstrates the bug, and the program \fBgood.c\fR demonstrates a non-buggy version. The difference between \fBgood.c\fR and \fBbad.c\fR is only \fIone character!!\fR Here is a summary of the bug. \fBgood.c\fR compiles without error. For \fBbad.c\fR, however, the assembler flags the following line and refuses to continue: @.nf @.in +5 move.w .30(pc,d0.w),d0 ram:ctmpA21.056: 784: ***ERROR - Pc relative out of byte range, -130. 1 errors @.in -5 @.fi \fBbad.c\fR contains the line \fIcase 'x':\fR, and \fBgood.c\fR has the line \fIcase 'y':\fR instead. This is the only difference between the two programs. Yet, one program compiles and the other doesn't! I tried compiling with all sorts of compiler options (particularly +P) but the bug remains. You will find the assembler output of the two programs very interesting. The rest of this letter includes the following: @.nf @.in +5 The source code for \fBbad.c\fR and \fBgood.c\fR; The output of \fBdiff bad.c good.c\fR; The output of \fBcc -AT bad.c\fR and \fBcc -AT good.c\fR; (maybe +P too... I forget.) The output of \fBdiff bad.asm good.asm\fR. @.in -5 @.fi I hope you find this useful! @.in +28 @.nf Sincerely, Daniel J. Barrett @//E*O*F letter// chmod u=rw,g=r,o=r letter echo x - net.letter sed 's/^@//' > "net.letter" <<'@//E*O*F net.letter//' I have found a VERY VERY VERY weird bug in Manx 3.6A (and earlier versions too). I have reported it to Manx, and I thought I'd describe it here. The following program fails to compile and assemble properly. You get the error message: move.w .30(pc,d0.w),d0 ^ ram:ctmpA21.056: 784: ***ERROR - Pc relative out of byte range, -130. 1 errors However, if you make the small change described in the program, it compiles fine. The difference is only ONE CHARACTER CONSTANT!!! The assembler output of the compiler, for the bad program and the good program, differs in the following way. (Output of the "diff" program.) 44c44 < ; case 'x': /* Change 'x' to ANY other character from */ --- > ; case 'y': /* Change 'x' to ANY other character from */ 131a132 > dc.w .29-.31-2 135,138c136,140 < cmp.l #55,d0 < bcc .29 < asl.l #1,d0 < move.w .30(pc,d0.w),d0 <===THIS IS THE BAD INSTRUCTION --- > cmp.l #56,d0 > bcc .29 > asl.l #1,d0 > lea .30,a0 > move.w (a0,d0.w),d0 Can anyone explain why this weird bug might happen?? --------------------------bad.c: cut here--------------------------- main() { char p; p = 'g'; switch(p) { case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'x': /* Change 'x' to ANY other character from */ /* 'n' to 'z', or possibly others, and this */ /* compiles and assembles without error. */ case 'B': case 'D': case 'F': case 'H': case 'I': case 'L': case 'O': case 'P': case 'X': break; default: puts("foo"); break; } } @//E*O*F net.letter// chmod u=rw,g=r,o=r net.letter echo Inspecting for damage in transit... temp=/tmp/shar$$; dtemp=/tmp/.shar$$ trap "rm -f $temp $dtemp; exit" 0 1 2 3 15 cat > $temp <<\!!! 20 70 420 asm.diffs 155 322 1929 bad.asm 38 87 522 bad.c 7 35 219 c.diffs 4 16 141 error.message 157 326 1954 good.asm 38 87 522 good.c 81 309 1944 letter 79 269 1667 net.letter 579 1521 9318 total !!! wc asm.diffs bad.asm bad.c c.diffs error.message good.asm good.c letter net.letter | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp if [ -s $dtemp ] then echo "Ouch [diff of wc output]:" ; cat $dtemp else echo "No problems found." fi exit 0 -- Dan Barrett ins_adjb@jhunix.UUCP UUCP barrett@cs.jhu.edu (128.220.13.4) ARPA Dept. of Computer Science, Johns Hopkins University, Baltimore, MD 21218