mirror of
https://github.com/python/cpython.git
synced 2025-08-03 08:34:29 +00:00
[3.11] gh-104615: don't make unsafe swaps in apply_static_swaps (GH-104620). (#104636)
(cherry picked from commit 0589c6a4d3
)
This commit is contained in:
parent
d78c3bcf6f
commit
667e4ece98
3 changed files with 40 additions and 0 deletions
|
@ -1064,6 +1064,24 @@ if 1:
|
|||
with self.subTest(source):
|
||||
self.assertEqual(actual_positions, expected_positions)
|
||||
|
||||
def test_apply_static_swaps(self):
|
||||
def f(x, y):
|
||||
a, a = x, y
|
||||
return a
|
||||
self.assertEqual(f("x", "y"), "y")
|
||||
|
||||
def test_apply_static_swaps_2(self):
|
||||
def f(x, y, z):
|
||||
a, b, a = x, y, z
|
||||
return a
|
||||
self.assertEqual(f("x", "y", "z"), "z")
|
||||
|
||||
def test_apply_static_swaps_3(self):
|
||||
def f(x, y, z):
|
||||
a, a, b = x, y, z
|
||||
return a
|
||||
self.assertEqual(f("x", "y", "z"), "y")
|
||||
|
||||
|
||||
@requires_debug_ranges()
|
||||
class TestSourcePositions(unittest.TestCase):
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Fix wrong ordering of assignments in code like ``a, a = x, y``. Contributed by
|
||||
Carl Meyer.
|
|
@ -8690,6 +8690,9 @@ swaptimize(basicblock *block, int *ix)
|
|||
#define SWAPPABLE(opcode) \
|
||||
((opcode) == STORE_FAST || (opcode) == POP_TOP)
|
||||
|
||||
#define STORES_TO(instr) \
|
||||
(((instr).i_opcode == STORE_FAST) ? (instr).i_oparg : -1)
|
||||
|
||||
static int
|
||||
next_swappable_instruction(basicblock *block, int i, int lineno)
|
||||
{
|
||||
|
@ -8741,6 +8744,23 @@ apply_static_swaps(basicblock *block, int i)
|
|||
return;
|
||||
}
|
||||
}
|
||||
// The reordering is not safe if the two instructions to be swapped
|
||||
// store to the same location, or if any intervening instruction stores
|
||||
// to the same location as either of them.
|
||||
int store_j = STORES_TO(block->b_instr[j]);
|
||||
int store_k = STORES_TO(block->b_instr[k]);
|
||||
if (store_j >= 0 || store_k >= 0) {
|
||||
if (store_j == store_k) {
|
||||
return;
|
||||
}
|
||||
for (int idx = j + 1; idx < k; idx++) {
|
||||
int store_idx = STORES_TO(block->b_instr[idx]);
|
||||
if (store_idx >= 0 && (store_idx == store_j || store_idx == store_k)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Success!
|
||||
swap->i_opcode = NOP;
|
||||
struct instr temp = block->b_instr[j];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue