From: borutr Date: Tue, 10 Mar 2009 21:36:15 +0000 (+0000) Subject: * src/mcs51/gen.c, src/z80/gen.c, src/hc08/gen.c, src/ds390/gen.c, X-Git-Url: https://git.gag.com/?p=fw%2Fsdcc;a=commitdiff_plain;h=b1a10c8ec5142594ec5698fa241d7433873ce710 * src/mcs51/gen.c, src/z80/gen.c, src/hc08/gen.c, src/ds390/gen.c, support/regression/tests/bug1875933.c: fixed bug #1875933: Evelyn jumps into the void thanks to Robert Larice git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5408 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 9c82f261..2b0f5cf0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-03-10 Borut Razem + + * src/mcs51/gen.c, src/z80/gen.c, src/hc08/gen.c, src/ds390/gen.c, + support/regression/tests/bug1875933.c: + fixed bug #1875933: Evelyn jumps into the void + thanks to Robert Larice + 2009-03-10 Raphael Neider * src/pic16/pcode.c (LinkFlow): fix invalid cast from pCodeLabel diff --git a/src/ds390/gen.c b/src/ds390/gen.c index 728bf80d..0d90d01e 100644 --- a/src/ds390/gen.c +++ b/src/ds390/gen.c @@ -1918,7 +1918,7 @@ aopPut (operand * result, const char *s, int offset) case AOP_CRY: // destination is carry for return-use-only d = (IS_OP_RUONLY (result)) ? "c" : aop->aopu.aop_dir; - + // source is no literal and not in carry if ((s != zero) && (s != one) && strcmp (s, "c")) { @@ -7829,7 +7829,7 @@ genOr (iCode * ic, iCode * ifx) // result = 1 if (size) emitcode ("setb", "%s", AOP (result)->aopu.aop_dir); - else + else if(ifx) continueIfTrue (ifx); goto release; } @@ -7847,7 +7847,7 @@ genOr (iCode * ic, iCode * ifx) emitLabel (tlbl); } else - { + { /* FIXME, thats pretty fishy, check for ifx!=0, testcase .. */ genIfxJump (ifx, "a", ic->next); goto release; } diff --git a/src/hc08/gen.c b/src/hc08/gen.c index a656eb5b..694dc860 100644 --- a/src/hc08/gen.c +++ b/src/hc08/gen.c @@ -5038,7 +5038,6 @@ genAnd (iCode * ic, iCode * ifx) if (AOP_TYPE (result) == AOP_CRY) { symbol *tlbl = NULL; - wassertl (ifx, "AOP_CRY result without ifx"); offset = 0; while (size--) @@ -5075,7 +5074,8 @@ genAnd (iCode * ic, iCode * ifx) } if (tlbl) emitLabel (tlbl); - genIfxJump (ifx, "a"); + if(ifx) + genIfxJump (ifx, "a"); goto release; } @@ -5202,7 +5202,6 @@ genOr (iCode * ic, iCode * ifx) if (AOP_TYPE (result) == AOP_CRY) { symbol *tlbl = NULL; - wassertl (ifx, "AOP_CRY result without ifx"); offset = 0; while (size--) @@ -5235,7 +5234,8 @@ genOr (iCode * ic, iCode * ifx) } if (tlbl) emitLabel (tlbl); - genIfxJump (ifx, "a"); + if(ifx) + genIfxJump (ifx, "a"); } if (AOP_TYPE (right) == AOP_LIT) diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index df242f30..9375087a 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -7210,7 +7210,7 @@ genOr (iCode * ic, iCode * ifx) // result = 1 if (size) emitcode ("setb", "%s", AOP (result)->aopu.aop_dir); - else + else if(ifx) continueIfTrue (ifx); goto release; } @@ -7228,7 +7228,7 @@ genOr (iCode * ic, iCode * ifx) emitLabel (tlbl); } else - { + { /* FIXME, thats pretty fishy, check for ifx!=0, testcase .. */ genIfxJump (ifx, "a", left, right, result, ic->next); goto release; } diff --git a/src/z80/gen.c b/src/z80/gen.c index 296cdf2e..a6e3a247 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -1412,7 +1412,7 @@ fetchLitPair (PAIR_ID pairId, asmop * left, int offset) new_high = (v_new >> 8) & 0xff; old_low = (v_old >> 0) & 0xff; old_high = (v_old >> 8) & 0xff; - + /* Change lower byte only. */ if(new_high == old_high) { @@ -4013,7 +4013,7 @@ genPlus (iCode * ic) emit2 ("ld a, b"); emit2 ("pop bc"); } - + } emit2 ("adc a,%s", aopGet (AOP (IC_RIGHT (ic)), 1, FALSE)); aopPut (AOP (IC_RESULT (ic)), "a", 1); @@ -4026,7 +4026,7 @@ genPlus (iCode * ic) if (offset == 0) { if(size == 0 && AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT && ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) == 1) - emit2 ("inc a"); + emit2 ("inc a"); else emit2 ("add a,%s", aopGet (AOP (IC_RIGHT (ic)), offset, FALSE)); } @@ -5386,6 +5386,7 @@ genAnd (iCode * ic, iCode * ifx) /* For the flags */ emit2 ("or a,a"); } + if (size || ifx) /* emit jmp only, if it is actually used */ emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100); } offset++; @@ -5569,9 +5570,19 @@ genOr (iCode * ic, iCode * ifx) bytelit = (lit >> (offset * 8)) & 0x0FFL; _moveA (aopGet (AOP (left), offset, FALSE)); - /* OR with any literal is the same as OR with itself. */ - emit2 ("or a,a"); - emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100); + + if (bytelit != 0) + { /* FIXME, allways true, shortcut possible */ + emit2 ("or a,%s", aopGet (AOP (right), offset, FALSE)); + } + else + { + /* For the flags */ + emit2 ("or a,a"); + } + + if (ifx) /* emit jmp only, if it is actually used */ + emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100); offset++; } @@ -8115,7 +8126,7 @@ setupForMemcpy (iCode *ic, int nparams, operand **pparams) { fetchPair (dest[i], AOP (pparams[i])); continue; - } + } } } } diff --git a/support/regression/tests/bug1875933.c b/support/regression/tests/bug1875933.c new file mode 100644 index 00000000..4ad27aaa --- /dev/null +++ b/support/regression/tests/bug1875933.c @@ -0,0 +1,102 @@ +/* + * bug1875933.c + */ + +#include +#include + +char identity(char x) +{ + return x; +} + +/* + * function genAnd() and genOr() in z80/gen.c + * were not prepared to handle the special case where ifx == 0 + */ + +void void_tand1(char x) +{ + char y = (identity(x) & 1) ? 42 : 43; +} + +void void_tand0(char x) +{ + char y = (identity(x) & 0) ? 42 : 43; +} + +/* + * function genOr() in z80/gen.c + * assumed identity of "or a, literal" and "or a,a" + * thats definitly not so + */ + +char tor1(char x) +{ + char y = (identity(x) | 1) ? 42 : 43; + return y; +} + +char tor0(char x) +{ + char y = (identity(x) | 0) ? 42 : 43; + return y; +} + +char tand1(char x) +{ + char y = (identity(x) & 1) ? 42 : 43; + return y; +} + +char tand0(char x) +{ + char y = (identity(x) & 0) ? 42 : 43; + return y; +} + +/* + * mcs51 segmentation fault + * + * function genOr() in mcs51/gen.c + * was not prepeared for ifx==0 + */ + +void void_tor1(char x) +{ + char y = (identity(x) | 1) ? 42 : 43; +} + +void void_tor0(char x) +{ + char y = (identity(x) | 0) ? 42 : 43; +} + +void void_tor(char x) +{ + char y = (identity(x) | x) ? 42 : 43; +} + +void +testBug(void) +{ + void_tand1(1); + void_tand1(0); + void_tand0(1); + void_tand0(0); + + ASSERT(tor1(1) == 42); + ASSERT(tor1(0) == 42); + ASSERT(tor0(1) == 42); + ASSERT(tor0(0) == 43); + ASSERT(tand1(1) == 42); + ASSERT(tand1(0) == 43); + ASSERT(tand0(1) == 43); + ASSERT(tand0(0) == 43); + + void_tor1(1); + void_tor1(0); + void_tor0(1); + void_tor0(0); + void_tor(0); +}