summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorCarl Meyer <carl@oddbird.net>2023-05-19 18:04:04 (GMT)
committerGitHub <noreply@github.com>2023-05-19 18:04:04 (GMT)
commit667e4ece9873146a99fc7c017b8a2be76765a715 (patch)
treee9503994dd8dec41584e7523dbac0b680b31a8e1 /Python
parentd78c3bcf6f4b616db247377eba4eff39119faa94 (diff)
downloadcpython-667e4ece9873146a99fc7c017b8a2be76765a715.zip
cpython-667e4ece9873146a99fc7c017b8a2be76765a715.tar.gz
cpython-667e4ece9873146a99fc7c017b8a2be76765a715.tar.bz2
[3.11] gh-104615: don't make unsafe swaps in apply_static_swaps (GH-104620). (#104636)
(cherry picked from commit 0589c6a4d3d822cace42050198cb9a5e99c879ad)
Diffstat (limited to 'Python')
-rw-r--r--Python/compile.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/Python/compile.c b/Python/compile.c
index f87a423..1c712fb 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -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];