mirror of
https://github.com/python/cpython.git
synced 2025-07-24 11:44:31 +00:00
SF bug #1053819: Segfault in tuple_of_constants
Peepholer could be fooled into misidentifying a tuple_of_constants. Added code to count consecutive occurrences of LOAD_CONST. Use the count to weed out the misidentified cases. Added a unittest.
This commit is contained in:
parent
368c0b22f8
commit
23109ef11e
2 changed files with 26 additions and 1 deletions
|
@ -83,6 +83,23 @@ class TestTranforms(unittest.TestCase):
|
||||||
self.assert_(elem in asm)
|
self.assert_(elem in asm)
|
||||||
self.assert_('BUILD_TUPLE' not in asm)
|
self.assert_('BUILD_TUPLE' not in asm)
|
||||||
|
|
||||||
|
# Bug 1053819: Tuple of constants misidentified when presented with:
|
||||||
|
# . . . opcode_with_arg 100 unary_opcode BUILD_TUPLE 1 . . .
|
||||||
|
# The following would segfault upon compilation
|
||||||
|
def crater():
|
||||||
|
(~[
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
|
],)
|
||||||
|
|
||||||
def test_elim_extra_return(self):
|
def test_elim_extra_return(self):
|
||||||
# RETURN LOAD_CONST None RETURN --> RETURN
|
# RETURN LOAD_CONST None RETURN --> RETURN
|
||||||
def f(x):
|
def f(x):
|
||||||
|
|
|
@ -419,15 +419,16 @@ tuple_of_constants(unsigned char *codestr, int n, PyObject *consts)
|
||||||
newconst = PyTuple_New(n);
|
newconst = PyTuple_New(n);
|
||||||
if (newconst == NULL)
|
if (newconst == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
len_consts = PyList_GET_SIZE(consts);
|
||||||
for (i=0 ; i<n ; i++) {
|
for (i=0 ; i<n ; i++) {
|
||||||
arg = GETARG(codestr, (i*3));
|
arg = GETARG(codestr, (i*3));
|
||||||
|
assert(arg < len_consts);
|
||||||
constant = PyList_GET_ITEM(consts, arg);
|
constant = PyList_GET_ITEM(consts, arg);
|
||||||
Py_INCREF(constant);
|
Py_INCREF(constant);
|
||||||
PyTuple_SET_ITEM(newconst, i, constant);
|
PyTuple_SET_ITEM(newconst, i, constant);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append folded constant onto consts */
|
/* Append folded constant onto consts */
|
||||||
len_consts = PyList_GET_SIZE(consts);
|
|
||||||
if (PyList_Append(consts, newconst)) {
|
if (PyList_Append(consts, newconst)) {
|
||||||
Py_DECREF(newconst);
|
Py_DECREF(newconst);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -501,6 +502,7 @@ optimize_code(PyObject *code, PyObject* consts, PyObject *names, PyObject *linen
|
||||||
unsigned char *lineno;
|
unsigned char *lineno;
|
||||||
int *addrmap = NULL;
|
int *addrmap = NULL;
|
||||||
int new_line, cum_orig_line, last_line, tabsiz;
|
int new_line, cum_orig_line, last_line, tabsiz;
|
||||||
|
int cumlc=0, lastlc=0; /* Count runs of consecutive LOAD_CONST codes */
|
||||||
unsigned int *blocks;
|
unsigned int *blocks;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
|
@ -536,6 +538,10 @@ optimize_code(PyObject *code, PyObject* consts, PyObject *names, PyObject *linen
|
||||||
for (i=0, nops=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
|
for (i=0, nops=0 ; i<codelen ; i += CODESIZE(codestr[i])) {
|
||||||
addrmap[i] = i - nops;
|
addrmap[i] = i - nops;
|
||||||
opcode = codestr[i];
|
opcode = codestr[i];
|
||||||
|
|
||||||
|
lastlc = cumlc;
|
||||||
|
cumlc = 0;
|
||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
|
|
||||||
/* Replace UNARY_NOT JUMP_IF_FALSE POP_TOP with
|
/* Replace UNARY_NOT JUMP_IF_FALSE POP_TOP with
|
||||||
|
@ -589,6 +595,7 @@ optimize_code(PyObject *code, PyObject* consts, PyObject *names, PyObject *linen
|
||||||
|
|
||||||
/* Skip over LOAD_CONST trueconst JUMP_IF_FALSE xx POP_TOP */
|
/* Skip over LOAD_CONST trueconst JUMP_IF_FALSE xx POP_TOP */
|
||||||
case LOAD_CONST:
|
case LOAD_CONST:
|
||||||
|
cumlc = lastlc + 1;
|
||||||
j = GETARG(codestr, i);
|
j = GETARG(codestr, i);
|
||||||
if (codestr[i+3] != JUMP_IF_FALSE ||
|
if (codestr[i+3] != JUMP_IF_FALSE ||
|
||||||
codestr[i+6] != POP_TOP ||
|
codestr[i+6] != POP_TOP ||
|
||||||
|
@ -607,6 +614,7 @@ optimize_code(PyObject *code, PyObject* consts, PyObject *names, PyObject *linen
|
||||||
j = GETARG(codestr, i);
|
j = GETARG(codestr, i);
|
||||||
h = i - 3 * j;
|
h = i - 3 * j;
|
||||||
if (h >= 0 &&
|
if (h >= 0 &&
|
||||||
|
j == lastlc &&
|
||||||
codestr[h] == LOAD_CONST &&
|
codestr[h] == LOAD_CONST &&
|
||||||
ISBASICBLOCK(blocks, h, 3*(j+1)) &&
|
ISBASICBLOCK(blocks, h, 3*(j+1)) &&
|
||||||
tuple_of_constants(&codestr[h], j, consts)) {
|
tuple_of_constants(&codestr[h], j, consts)) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue