diff -r c6fd0f3aadc4 Lib/test/test_long.py --- a/Lib/test/test_long.py Mon Aug 29 15:59:48 2016 +0300 +++ b/Lib/test/test_long.py Mon Aug 29 15:39:24 2016 +0100 @@ -878,6 +878,21 @@ self.check_truediv(-x, y) self.check_truediv(-x, -y) + def test_lshift_of_zero(self): + self.assertEqual(0 << 0, 0) + self.assertEqual(0 << 10, 0) + with self.assertRaises(ValueError): + 0 << -1 + + @support.cpython_only + def test_huge_lshift_of_zero(self): + # Shouldn't try to allocate memory for a huge shift. See issue #27870. + # Other implementations may have a different boundary for overflow, + # or not raise at all. + self.assertEqual(0 << sys.maxsize, 0) + with self.assertRaises(OverflowError): + 0 << (sys.maxsize + 1) + def test_small_ints(self): for i in range(-5, 257): self.assertIs(i, i + 0) diff -r c6fd0f3aadc4 Objects/longobject.c --- a/Objects/longobject.c Mon Aug 29 15:59:48 2016 +0300 +++ b/Objects/longobject.c Mon Aug 29 15:39:24 2016 +0100 @@ -4276,6 +4276,11 @@ PyErr_SetString(PyExc_ValueError, "negative shift count"); return NULL; } + + if (Py_SIZE(a) == 0) { + return PyLong_FromLong(0); + } + /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */ wordshift = shiftby / PyLong_SHIFT; remshift = shiftby - wordshift * PyLong_SHIFT;