mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	gh-132011: Fix crash on invalid CALL_LIST_APPEND deoptimization (#132018)
				
					
				
			Co-authored-by: Victor Stinner <vstinner@python.org> Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
This commit is contained in:
		
							parent
							
								
									42e3a8410b
								
							
						
					
					
						commit
						c0661df42a
					
				
					 5 changed files with 32 additions and 4 deletions
				
			
		| 
						 | 
					@ -4,7 +4,7 @@
 | 
				
			||||||
from test import list_tests, support
 | 
					from test import list_tests, support
 | 
				
			||||||
from test.support import cpython_only
 | 
					from test.support import cpython_only
 | 
				
			||||||
from test.support.import_helper import import_module
 | 
					from test.support.import_helper import import_module
 | 
				
			||||||
from test.support.script_helper import assert_python_failure
 | 
					from test.support.script_helper import assert_python_failure, assert_python_ok
 | 
				
			||||||
import pickle
 | 
					import pickle
 | 
				
			||||||
import unittest
 | 
					import unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -332,5 +332,25 @@ def test_no_memory(self):
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.assertNotEqual(rc, -int(signal.SIGSEGV))
 | 
					            self.assertNotEqual(rc, -int(signal.SIGSEGV))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_deopt_from_append_list(self):
 | 
				
			||||||
 | 
					        # gh-132011: it used to crash, because
 | 
				
			||||||
 | 
					        # of `CALL_LIST_APPEND` specialization failure.
 | 
				
			||||||
 | 
					        code = textwrap.dedent("""
 | 
				
			||||||
 | 
					            l = []
 | 
				
			||||||
 | 
					            def lappend(l, x, y):
 | 
				
			||||||
 | 
					                l.append((x, y))
 | 
				
			||||||
 | 
					            for x in range(3):
 | 
				
			||||||
 | 
					                lappend(l, None, None)
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                lappend(list, None, None)
 | 
				
			||||||
 | 
					            except TypeError:
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                raise AssertionError
 | 
				
			||||||
 | 
					        """)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        rc, _, _ = assert_python_ok("-c", code)
 | 
				
			||||||
 | 
					        self.assertEqual(rc, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    unittest.main()
 | 
					    unittest.main()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					Fix crash when calling :meth:`!list.append` as an unbound method.
 | 
				
			||||||
| 
						 | 
					@ -4235,7 +4235,7 @@ dummy_func(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            PyInterpreterState *interp = tstate->interp;
 | 
					            PyInterpreterState *interp = tstate->interp;
 | 
				
			||||||
            DEOPT_IF(callable_o != interp->callable_cache.list_append);
 | 
					            DEOPT_IF(callable_o != interp->callable_cache.list_append);
 | 
				
			||||||
            assert(self_o != NULL);
 | 
					            DEOPT_IF(self_o == NULL);
 | 
				
			||||||
            DEOPT_IF(!PyList_Check(self_o));
 | 
					            DEOPT_IF(!PyList_Check(self_o));
 | 
				
			||||||
            DEOPT_IF(!LOCK_OBJECT(self_o));
 | 
					            DEOPT_IF(!LOCK_OBJECT(self_o));
 | 
				
			||||||
            STAT_INC(CALL, hit);
 | 
					            STAT_INC(CALL, hit);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								Python/executor_cases.c.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										5
									
								
								Python/executor_cases.c.h
									
										
									
										generated
									
									
									
								
							| 
						 | 
					@ -5710,7 +5710,10 @@
 | 
				
			||||||
                UOP_STAT_INC(uopcode, miss);
 | 
					                UOP_STAT_INC(uopcode, miss);
 | 
				
			||||||
                JUMP_TO_JUMP_TARGET();
 | 
					                JUMP_TO_JUMP_TARGET();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            assert(self_o != NULL);
 | 
					            if (self_o == NULL) {
 | 
				
			||||||
 | 
					                UOP_STAT_INC(uopcode, miss);
 | 
				
			||||||
 | 
					                JUMP_TO_JUMP_TARGET();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            if (!PyList_Check(self_o)) {
 | 
					            if (!PyList_Check(self_o)) {
 | 
				
			||||||
                UOP_STAT_INC(uopcode, miss);
 | 
					                UOP_STAT_INC(uopcode, miss);
 | 
				
			||||||
                JUMP_TO_JUMP_TARGET();
 | 
					                JUMP_TO_JUMP_TARGET();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										6
									
								
								Python/generated_cases.c.h
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								Python/generated_cases.c.h
									
										
									
										generated
									
									
									
								
							| 
						 | 
					@ -3265,7 +3265,11 @@
 | 
				
			||||||
                assert(_PyOpcode_Deopt[opcode] == (CALL));
 | 
					                assert(_PyOpcode_Deopt[opcode] == (CALL));
 | 
				
			||||||
                JUMP_TO_PREDICTED(CALL);
 | 
					                JUMP_TO_PREDICTED(CALL);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            assert(self_o != NULL);
 | 
					            if (self_o == NULL) {
 | 
				
			||||||
 | 
					                UPDATE_MISS_STATS(CALL);
 | 
				
			||||||
 | 
					                assert(_PyOpcode_Deopt[opcode] == (CALL));
 | 
				
			||||||
 | 
					                JUMP_TO_PREDICTED(CALL);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            if (!PyList_Check(self_o)) {
 | 
					            if (!PyList_Check(self_o)) {
 | 
				
			||||||
                UPDATE_MISS_STATS(CALL);
 | 
					                UPDATE_MISS_STATS(CALL);
 | 
				
			||||||
                assert(_PyOpcode_Deopt[opcode] == (CALL));
 | 
					                assert(_PyOpcode_Deopt[opcode] == (CALL));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue