]> granicus.if.org Git - python/commitdiff
Fix SF bug 1441486: bad unary minus folding in compiler.
authorNeil Schemenauer <nascheme@enme.ucalgary.ca>
Sun, 9 Jul 2006 21:19:29 +0000 (21:19 +0000)
committerNeil Schemenauer <nascheme@enme.ucalgary.ca>
Sun, 9 Jul 2006 21:19:29 +0000 (21:19 +0000)
Lib/test/test_compile.py
Misc/NEWS
Python/ast.c

index 7c24d1b5c570d0b9e7dd91f11d5773deeb6ea040..bacec35766c05c29746c4a53e4c51e8a9cf4c74d 100644 (file)
@@ -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
index f01aff2207e58d1bed04bd66f354615f5c174816..bc34360ab7ab16489850a647c1159611ddf536d9 100644 (file)
--- 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.
 
index 6fd1ebe2c9994f8d275e0d22e83688df7673525e..cd0649eb518918014fe77d60b49bcd34964f23c2 100644 (file)
@@ -1483,6 +1483,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)
 {
@@ -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: