summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2013-05-16 13:04:15 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2013-05-16 13:04:15 -0300
commitd2209c07419aac2cac63dd6d31f5e886a2fdf7fa (patch)
treeb328c2e5e18f138bc9476b88913e93ce4fec049b
parent39808bb97078aafbf1b614a6d224c4a71b9ab46b (diff)
downloadlua-github-d2209c07419aac2cac63dd6d31f5e886a2fdf7fa.tar.gz
bug: Wrong error message in some short-cut expressions
-rw-r--r--ldebug.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/ldebug.c b/ldebug.c
index 92374d50..a585075c 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -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;
}
}