diff options
author | Carl Meyer <carl@oddbird.net> | 2023-05-18 21:22:03 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-18 21:22:03 (GMT) |
commit | 0589c6a4d3d822cace42050198cb9a5e99c879ad (patch) | |
tree | ae6785cbe277413976d6513d80f42206477d5f0b /Python | |
parent | dcdc90d384723920e8dea0ee04eae8c219333634 (diff) | |
download | cpython-0589c6a4d3d822cace42050198cb9a5e99c879ad.zip cpython-0589c6a4d3d822cace42050198cb9a5e99c879ad.tar.gz cpython-0589c6a4d3d822cace42050198cb9a5e99c879ad.tar.bz2 |
gh-104615: don't make unsafe swaps in apply_static_swaps (#104620)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/compile.c | 4 | ||||
-rw-r--r-- | Python/flowgraph.c | 22 |
2 files changed, 24 insertions, 2 deletions
diff --git a/Python/compile.c b/Python/compile.c index 07f8d66..96cd6da 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -7996,7 +7996,7 @@ finally: } PyObject * -_PyCompile_OptimizeCfg(PyObject *instructions, PyObject *consts) +_PyCompile_OptimizeCfg(PyObject *instructions, PyObject *consts, int nlocals) { PyObject *res = NULL; PyObject *const_cache = PyDict_New(); @@ -8008,7 +8008,7 @@ _PyCompile_OptimizeCfg(PyObject *instructions, PyObject *consts) if (instructions_to_cfg(instructions, &g) < 0) { goto error; } - int code_flags = 0, nlocals = 0, nparams = 0, firstlineno = 1; + int code_flags = 0, nparams = 0, firstlineno = 1; if (_PyCfg_OptimizeCodeUnit(&g, consts, const_cache, code_flags, nlocals, nparams, firstlineno) < 0) { goto error; diff --git a/Python/flowgraph.c b/Python/flowgraph.c index 7f790b7..f8039a4 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -1293,6 +1293,11 @@ swaptimize(basicblock *block, int *ix) (opcode) == STORE_FAST_MAYBE_NULL || \ (opcode) == POP_TOP) +#define STORES_TO(instr) \ + (((instr).i_opcode == STORE_FAST || \ + (instr).i_opcode == STORE_FAST_MAYBE_NULL) \ + ? (instr).i_oparg : -1) + static int next_swappable_instruction(basicblock *block, int i, int lineno) { @@ -1344,6 +1349,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! INSTR_SET_OP0(swap, NOP); cfg_instr temp = block->b_instr[j]; |