mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	Fix SF bug 1441486: bad unary minus folding in compiler.
This commit is contained in:
		
							parent
							
								
									0e07b60a4e
								
							
						
					
					
						commit
						6ec6ab02c3
					
				
					 3 changed files with 60 additions and 20 deletions
				
			
		|  | @ -211,6 +211,10 @@ def test_unary_minus(self): | |||
|             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. | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										73
									
								
								Python/ast.c
									
										
									
									
									
								
							
							
						
						
									
										73
									
								
								Python/ast.c
									
										
									
									
									
								
							|  | @ -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: | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Neil Schemenauer
						Neil Schemenauer