mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
GH-123044: Give the POP_TOP
after a case test a location in the body, not the pattern. (GH-130627)
This commit is contained in:
parent
91d6db7ee0
commit
be046ee6e0
6 changed files with 52 additions and 6 deletions
|
@ -58,6 +58,7 @@ typedef struct {
|
|||
.end_col_offset = (n)->end_col_offset }
|
||||
|
||||
static const _Py_SourceLocation NO_LOCATION = {-1, -1, -1, -1};
|
||||
static const _Py_SourceLocation NEXT_LOCATION = {-2, -2, -2, -2};
|
||||
|
||||
/* __future__ information */
|
||||
typedef struct {
|
||||
|
|
|
@ -1681,6 +1681,35 @@ class TestBranchAndJumpEvents(CheckEvents):
|
|||
('branch left', 'func', 12, 12)])
|
||||
|
||||
|
||||
def test_match(self):
|
||||
|
||||
def func(v=1):
|
||||
x = 0
|
||||
for v in range(4):
|
||||
match v:
|
||||
case 1:
|
||||
x += 1
|
||||
case 2:
|
||||
x += 2
|
||||
case _:
|
||||
x += 3
|
||||
return x
|
||||
|
||||
self.check_events(func, recorders = BRANCHES_RECORDERS, expected = [
|
||||
('branch left', 'func', 2, 2),
|
||||
('branch right', 'func', 4, 6),
|
||||
('branch right', 'func', 6, 8),
|
||||
('branch left', 'func', 2, 2),
|
||||
('branch left', 'func', 4, 5),
|
||||
('branch left', 'func', 2, 2),
|
||||
('branch right', 'func', 4, 6),
|
||||
('branch left', 'func', 6, 7),
|
||||
('branch left', 'func', 2, 2),
|
||||
('branch right', 'func', 4, 6),
|
||||
('branch right', 'func', 6, 8),
|
||||
('branch right', 'func', 2, 10)])
|
||||
|
||||
|
||||
class TestBranchConsistency(MonitoringTestBase, unittest.TestCase):
|
||||
|
||||
def check_branches(self, run_func, test_func=None, tool=TEST_TOOL, recorders=BRANCH_OFFSET_RECORDERS):
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Make sure that the location of branch targets in ``match`` cases is in the
|
||||
body, not the pattern.
|
|
@ -291,6 +291,7 @@ write_location_info_entry(struct assembler* a, location loc, int isize)
|
|||
RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, len*2));
|
||||
}
|
||||
if (loc.lineno < 0) {
|
||||
assert(loc.lineno == NO_LOCATION.lineno);
|
||||
write_location_info_none(a, isize);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
@ -341,6 +342,18 @@ assemble_location_info(struct assembler *a, instr_sequence *instrs,
|
|||
{
|
||||
a->a_lineno = firstlineno;
|
||||
location loc = NO_LOCATION;
|
||||
for (int i = instrs->s_used-1; i >= 0; i--) {
|
||||
instruction *instr = &instrs->s_instrs[i];
|
||||
if (same_location(instr->i_loc, NEXT_LOCATION)) {
|
||||
if (IS_TERMINATOR_OPCODE(instr->i_opcode)) {
|
||||
instr->i_loc = NO_LOCATION;
|
||||
}
|
||||
else {
|
||||
assert(i < instrs->s_used-1);
|
||||
instr->i_loc = instr[1].i_loc;
|
||||
}
|
||||
}
|
||||
}
|
||||
int size = 0;
|
||||
for (int i = 0; i < instrs->s_used; i++) {
|
||||
instruction *instr = &instrs->s_instrs[i];
|
||||
|
|
|
@ -6124,7 +6124,8 @@ codegen_match_inner(compiler *c, stmt_ty s, pattern_context *pc)
|
|||
}
|
||||
// Success! Pop the subject off, we're done with it:
|
||||
if (i != cases - has_default - 1) {
|
||||
ADDOP(c, LOC(m->pattern), POP_TOP);
|
||||
/* Use the next location to give better locations for branch events */
|
||||
ADDOP(c, NEXT_LOCATION, POP_TOP);
|
||||
}
|
||||
VISIT_SEQ(c, stmt, m->body);
|
||||
ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
|
||||
|
|
|
@ -1078,8 +1078,8 @@ basicblock_remove_redundant_nops(basicblock *bb) {
|
|||
location next_loc = NO_LOCATION;
|
||||
for (int next_i=0; next_i < next->b_iused; next_i++) {
|
||||
cfg_instr *instr = &next->b_instr[next_i];
|
||||
if (instr->i_opcode == NOP && instr->i_loc.lineno == NO_LOCATION.lineno) {
|
||||
/* Skip over NOPs without location, they will be removed */
|
||||
if (instr->i_opcode == NOP && instr->i_loc.lineno < 0) {
|
||||
/* Skip over NOPs without a location, they will be removed */
|
||||
continue;
|
||||
}
|
||||
next_loc = instr->i_loc;
|
||||
|
@ -2976,7 +2976,7 @@ propagate_line_numbers(basicblock *entryblock) {
|
|||
|
||||
location prev_location = NO_LOCATION;
|
||||
for (int i = 0; i < b->b_iused; i++) {
|
||||
if (b->b_instr[i].i_loc.lineno < 0) {
|
||||
if (b->b_instr[i].i_loc.lineno == NO_LOCATION.lineno) {
|
||||
b->b_instr[i].i_loc = prev_location;
|
||||
}
|
||||
else {
|
||||
|
@ -2985,7 +2985,7 @@ propagate_line_numbers(basicblock *entryblock) {
|
|||
}
|
||||
if (BB_HAS_FALLTHROUGH(b) && b->b_next->b_predecessors == 1) {
|
||||
if (b->b_next->b_iused > 0) {
|
||||
if (b->b_next->b_instr[0].i_loc.lineno < 0) {
|
||||
if (b->b_next->b_instr[0].i_loc.lineno == NO_LOCATION.lineno) {
|
||||
b->b_next->b_instr[0].i_loc = prev_location;
|
||||
}
|
||||
}
|
||||
|
@ -2993,7 +2993,7 @@ propagate_line_numbers(basicblock *entryblock) {
|
|||
if (is_jump(last)) {
|
||||
basicblock *target = last->i_target;
|
||||
if (target->b_predecessors == 1) {
|
||||
if (target->b_instr[0].i_loc.lineno < 0) {
|
||||
if (target->b_instr[0].i_loc.lineno == NO_LOCATION.lineno) {
|
||||
target->b_instr[0].i_loc = prev_location;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue