diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-05-16 13:04:15 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-05-16 13:04:15 -0300 |
commit | d2209c07419aac2cac63dd6d31f5e886a2fdf7fa (patch) | |
tree | b328c2e5e18f138bc9476b88913e93ce4fec049b | |
parent | 39808bb97078aafbf1b614a6d224c4a71b9ab46b (diff) | |
download | lua-github-d2209c07419aac2cac63dd6d31f5e886a2fdf7fa.tar.gz |
bug: Wrong error message in some short-cut expressions
-rw-r--r-- | ldebug.c | 29 |
1 files changed, 21 insertions, 8 deletions
@@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 2.90.1.1 2013/04/12 18:48:47 roberto Exp roberto $ +** $Id: ldebug.c,v 2.90.1.2 2013/05/06 17:20:22 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -327,12 +327,20 @@ static void kname (Proto *p, int pc, int c, const char **name) { } +static int filterpc (int pc, int jmptarget) { + if (pc < jmptarget) /* is code conditional (inside a jump)? */ + return -1; /* cannot know who sets that register */ + else return pc; /* current position sets that register */ +} + + /* ** try to find last instruction before 'lastpc' that modified register 'reg' */ static int findsetreg (Proto *p, int lastpc, int reg) { int pc; int setreg = -1; /* keep last instruction that changed 'reg' */ + int jmptarget = 0; /* any code before this address is conditional */ for (pc = 0; pc < lastpc; pc++) { Instruction i = p->code[pc]; OpCode op = GET_OPCODE(i); @@ -341,33 +349,38 @@ static int findsetreg (Proto *p, int lastpc, int reg) { case OP_LOADNIL: { int b = GETARG_B(i); if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ - setreg = pc; + setreg = filterpc(pc, jmptarget); break; } case OP_TFORCALL: { - if (reg >= a + 2) setreg = pc; /* affect all regs above its base */ + if (reg >= a + 2) /* affect all regs above its base */ + setreg = filterpc(pc, jmptarget); break; } case OP_CALL: case OP_TAILCALL: { - if (reg >= a) setreg = pc; /* affect all registers above base */ + if (reg >= a) /* affect all registers above base */ + setreg = filterpc(pc, jmptarget); break; } case OP_JMP: { int b = GETARG_sBx(i); int dest = pc + 1 + b; /* jump is forward and do not skip `lastpc'? */ - if (pc < dest && dest <= lastpc) - pc += b; /* do the jump */ + if (pc < dest && dest <= lastpc) { + if (dest > jmptarget) + jmptarget = dest; /* update 'jmptarget' */ + } break; } case OP_TEST: { - if (reg == a) setreg = pc; /* jumped code can change 'a' */ + if (reg == a) /* jumped code can change 'a' */ + setreg = filterpc(pc, jmptarget); break; } default: if (testAMode(op) && reg == a) /* any instruction that set A */ - setreg = pc; + setreg = filterpc(pc, jmptarget); break; } } |