dibyendumajumdar/ravi

Wrong Type Deduction for BNOT

XmiliaH opened this issue · 8 comments

In the case where BNOT receives a float as input, it will deduce that the output is a float too. However, this is wrong since at runtime BNOT will cast the float to an integer first and return an integer.
The problem seems to be in the parser near

ravi/src/lcode.c

Line 1580 in 56a59a1

case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */

To demonstrate the issue the following code will fail with src/lvm.c:2422: luaV_execute: Assertion `((((rb))->tt_) == (((3) | ((0) << 4))))' failed.

local function f()
    local x:number = 1.0
    return (~x) + 1
end
print(f())

The bytecode from function f is

1       [2]     LOADK           0 -1    ; 1.0
2       [3]     BNOT            1 0
3       [3]     ADDFI           1 1 -2  ; - 1
4       [3]     RETURN          1 2
5       [4]     RETURN          0 1

with the unexpected ADDFI.

Thank you for the report. I will check

The problem seems to be that BNOT will convert floats that have no decimal to int, so ADDFI fails because it was expecting a float.

I have a fix but I need to test it

I have pushed some fixes for this and the others you reported. Please check and let me know if the issues reported are now fixed

The LEN one ist not fully fixed. I noticed that it didn't fail the way I intended since the array indexing was put in parenthesis. So the following will fail with the given description:

debug.setmetatable(1, {
    __len = function()
        return "123"
    end
})

local function f(x:integer[])
    return #x[1] + 1
end

print(f(table.intarray(2)))

The others looked good to me, but I noticed that in ravi_resize_array the t->size + 10 could overflow.

Okay looks like you found a different bug here - the expression #x results in int but then int[1] is not correctly being handled

The problem here is that

ravi/src/lcode.c

Line 1270 in fe7c76f

int r = luaK_exp2anyreg(fs, e); /* opcodes operate only on registers */
can change the result of e->ravi_type. You need to swap this and the first line of the function.

I think you are correct. Thank you!