Negation in constant folding of '>>' may overflow
diff --git a/lobject.c b/lobject.c
index a2c0060..03e2798 100644
--- a/lobject.c
+++ b/lobject.c
@@ -62,7 +62,7 @@
case LUA_OPBOR: return intop(|, v1, v2);
case LUA_OPBXOR: return intop(^, v1, v2);
case LUA_OPSHL: return luaV_shiftl(v1, v2);
- case LUA_OPSHR: return luaV_shiftl(v1, -v2);
+ case LUA_OPSHR: return luaV_shiftr(v1, v2);
case LUA_OPUNM: return intop(-, 0, v1);
case LUA_OPBNOT: return intop(^, ~l_castS2U(0), v1);
default: lua_assert(0); return 0;
diff --git a/lvm.c b/lvm.c
index 614df05..73a19ba 100644
--- a/lvm.c
+++ b/lvm.c
@@ -765,12 +765,10 @@
/* number of bits in an integer */
#define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT)
+
/*
** Shift left operation. (Shift right just negates 'y'.)
*/
-#define luaV_shiftr(x,y) luaV_shiftl(x,intop(-, 0, y))
-
-
lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) {
if (y < 0) { /* shift right? */
if (y <= -NBITS) return 0;
diff --git a/lvm.h b/lvm.h
index 1bc16f3..dba1ad2 100644
--- a/lvm.h
+++ b/lvm.h
@@ -110,6 +110,11 @@
luaC_barrierback(L, gcvalue(t), v); }
+/*
+** Shift right is the same as shift left with a negative 'y'
+*/
+#define luaV_shiftr(x,y) luaV_shiftl(x,intop(-, 0, y))
+
LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2);
diff --git a/testes/bitwise.lua b/testes/bitwise.lua
index 9509f7f..dd0a1a9 100644
--- a/testes/bitwise.lua
+++ b/testes/bitwise.lua
@@ -38,6 +38,18 @@
assert(a | b ~ c & d == 0xF4000000 << 32)
assert(~~a == a and ~a == -1 ~ a and -d == ~d + 1)
+
+do -- constant folding
+ local code = string.format("return -1 >> %d", math.maxinteger)
+ assert(load(code)() == 0)
+ local code = string.format("return -1 >> %d", math.mininteger)
+ assert(load(code)() == 0)
+ local code = string.format("return -1 << %d", math.maxinteger)
+ assert(load(code)() == 0)
+ local code = string.format("return -1 << %d", math.mininteger)
+ assert(load(code)() == 0)
+end
+
assert(-1 >> 1 == (1 << (numbits - 1)) - 1 and 1 << 31 == 0x80000000)
assert(-1 >> (numbits - 1) == 1)
assert(-1 >> numbits == 0 and