mirror of
https://github.com/python/cpython.git
synced 2025-10-02 05:12:23 +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):
|
with self.subTest(source):
|
||||||
self.assertEqual(actual_positions, expected_positions)
|
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()
|
@requires_debug_ranges()
|
||||||
class TestSourcePositions(unittest.TestCase):
|
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) \
|
#define SWAPPABLE(opcode) \
|
||||||
((opcode) == STORE_FAST || (opcode) == POP_TOP)
|
((opcode) == STORE_FAST || (opcode) == POP_TOP)
|
||||||
|
|
||||||
|
#define STORES_TO(instr) \
|
||||||
|
(((instr).i_opcode == STORE_FAST) ? (instr).i_oparg : -1)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
next_swappable_instruction(basicblock *block, int i, int lineno)
|
next_swappable_instruction(basicblock *block, int i, int lineno)
|
||||||
{
|
{
|
||||||
|
@ -8741,6 +8744,23 @@ apply_static_swaps(basicblock *block, int i)
|
||||||
return;
|
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!
|
// Success!
|
||||||
swap->i_opcode = NOP;
|
swap->i_opcode = NOP;
|
||||||
struct instr temp = block->b_instr[j];
|
struct instr temp = block->b_instr[j];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue