summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Schemenauer <nascheme@enme.ucalgary.ca>2006-07-09 21:19:29 (GMT)
committerNeil Schemenauer <nascheme@enme.ucalgary.ca>2006-07-09 21:19:29 (GMT)
commit6ec6ab02c33b1b879fef7058bcfecd4edaa66bd9 (patch)
tree8774584d013bbdd1538b5ef8b9813805f2a8bf05
parent0e07b60a4e44129cfafaeacac765cf957e2ea219 (diff)
downloadcpython-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.py4
-rw-r--r--Misc/NEWS3
-rw-r--r--Python/ast.c73
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
diff --git a/Misc/NEWS b/Misc/NEWS
index f01aff2..bc34360 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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: