diff options
author | Neil Schemenauer <nascheme@enme.ucalgary.ca> | 2006-07-09 21:19:29 (GMT) |
---|---|---|
committer | Neil Schemenauer <nascheme@enme.ucalgary.ca> | 2006-07-09 21:19:29 (GMT) |
commit | 6ec6ab02c33b1b879fef7058bcfecd4edaa66bd9 (patch) | |
tree | 8774584d013bbdd1538b5ef8b9813805f2a8bf05 | |
parent | 0e07b60a4e44129cfafaeacac765cf957e2ea219 (diff) | |
download | cpython-6ec6ab02c33b1b879fef7058bcfecd4edaa66bd9.zip cpython-6ec6ab02c33b1b879fef7058bcfecd4edaa66bd9.tar.gz cpython-6ec6ab02c33b1b879fef7058bcfecd4edaa66bd9.tar.bz2 |
Fix SF bug 1441486: bad unary minus folding in compiler.
-rw-r--r-- | Lib/test/test_compile.py | 4 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Python/ast.c | 73 |
3 files changed, 60 insertions, 20 deletions
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 7c24d1b..bacec35 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -211,6 +211,10 @@ if 1: self.assertEqual(eval("-" + all_one_bits), -18446744073709551615L) else: self.fail("How many bits *does* this machine have???") + # Verify treatment of contant folding on -(sys.maxint+1) + # i.e. -2147483648 on 32 bit platforms. Should return int, not long. + self.assertTrue(isinstance(eval("%s" % (-sys.maxint - 1)), int)) + self.assertTrue(isinstance(eval("%s" % (-sys.maxint - 2)), long)) def test_sequence_unpacking_error(self): # Verify sequence packing/unpacking with "or". SF bug #757818 @@ -12,6 +12,9 @@ What's New in Python 2.5 beta 2? Core and builtins ----------------- +- Bug #1441486: The literal representation of -(sys.maxint - 1) + again evaluates to a int object, not a long. + - Bug #1501934: The scope of global variables that are locally assigned using augmented assignment is now correctly determined. diff --git a/Python/ast.c b/Python/ast.c index 6fd1ebe..cd0649e 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -1484,6 +1484,57 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) } static expr_ty +ast_for_factor(struct compiling *c, const node *n) +{ + node *pfactor, *ppower, *patom, *pnum; + expr_ty expression; + + /* If the unary - operator is applied to a constant, don't generate + a UNARY_NEGATIVE opcode. Just store the approriate value as a + constant. The peephole optimizer already does something like + this but it doesn't handle the case where the constant is + (sys.maxint - 1). In that case, we want a PyIntObject, not a + PyLongObject. + */ + if (TYPE(CHILD(n, 0)) == MINUS + && NCH(n) == 2 + && TYPE((pfactor = CHILD(n, 1))) == factor + && NCH(pfactor) == 1 + && TYPE((ppower = CHILD(pfactor, 0))) == power + && NCH(ppower) == 1 + && TYPE((patom = CHILD(ppower, 0))) == atom + && TYPE((pnum = CHILD(patom, 0))) == NUMBER) { + char *s = PyObject_MALLOC(strlen(STR(pnum)) + 2); + if (s == NULL) + return NULL; + s[0] = '-'; + strcpy(s + 1, STR(pnum)); + PyObject_FREE(STR(pnum)); + STR(pnum) = s; + return ast_for_atom(c, patom); + } + + expression = ast_for_expr(c, CHILD(n, 1)); + if (!expression) + return NULL; + + switch (TYPE(CHILD(n, 0))) { + case PLUS: + return UnaryOp(UAdd, expression, LINENO(n), n->n_col_offset, + c->c_arena); + case MINUS: + return UnaryOp(USub, expression, LINENO(n), n->n_col_offset, + c->c_arena); + case TILDE: + return UnaryOp(Invert, expression, LINENO(n), + n->n_col_offset, c->c_arena); + } + PyErr_Format(PyExc_SystemError, "unhandled factor: %d", + TYPE(CHILD(n, 0))); + return NULL; +} + +static expr_ty ast_for_power(struct compiling *c, const node *n) { /* power: atom trailer* ('**' factor)* @@ -1662,30 +1713,12 @@ ast_for_expr(struct compiling *c, const node *n) } return Yield(exp, LINENO(n), n->n_col_offset, c->c_arena); } - case factor: { - expr_ty expression; - + case factor: if (NCH(n) == 1) { n = CHILD(n, 0); goto loop; } - - expression = ast_for_expr(c, CHILD(n, 1)); - if (!expression) - return NULL; - - switch (TYPE(CHILD(n, 0))) { - case PLUS: - return UnaryOp(UAdd, expression, LINENO(n), n->n_col_offset, c->c_arena); - case MINUS: - return UnaryOp(USub, expression, LINENO(n), n->n_col_offset, c->c_arena); - case TILDE: - return UnaryOp(Invert, expression, LINENO(n), n->n_col_offset, c->c_arena); - } - PyErr_Format(PyExc_SystemError, "unhandled factor: %d", - TYPE(CHILD(n, 0))); - break; - } + return ast_for_factor(c, n); case power: return ast_for_power(c, n); default: |