Skip to content

Commit ed14019

Browse files
committed
Add assertion in liveliness computation
Assert that a live-range does not start, while one for the same variable is already active. To satisfy this constraint, explicitly exclude writes from JMP_SET and COALESCE. They were previously also handled correctly, because their result variable was only killed after the second write to it after the false branch. This just makes it more explicit.
1 parent 249915f commit ed14019

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

Zend/zend_opcode.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -941,9 +941,12 @@ static zend_always_inline uint32_t *generate_var_liveliness_info_ex(zend_op_arra
941941
&& opline->opcode != ZEND_BOOL
942942
&& opline->opcode != ZEND_JMPZ_EX
943943
&& opline->opcode != ZEND_JMPNZ_EX
944-
/* these two consecutive ops appear on ternary,
945-
* the result of true branch is undefined for false branch */
944+
/* These opcodes write the result of the true branch of a ternary, short
945+
* ternary or coalesce and are immediately followed by the instructions
946+
* for the false branch (where this result is not live) */
946947
&& (opline->opcode != ZEND_QM_ASSIGN || (opline + 1)->opcode != ZEND_JMP)
948+
&& opline->opcode != ZEND_JMP_SET
949+
&& opline->opcode != ZEND_COALESCE
947950
/* exception for opcache, it might nowhere use the temporary
948951
* (anyway bool, so no need to free) */
949952
&& opline->opcode != ZEND_CASE
@@ -959,14 +962,17 @@ static zend_always_inline uint32_t *generate_var_liveliness_info_ex(zend_op_arra
959962
&& opline->opcode != ZEND_DECLARE_INHERITED_CLASS
960963
&& opline->opcode != ZEND_DECLARE_INHERITED_CLASS_DELAYED
961964
&& opline->opcode != ZEND_DECLARE_ANON_CLASS
962-
&& opline->opcode != ZEND_DECLARE_ANON_INHERITED_CLASS) {
965+
&& opline->opcode != ZEND_DECLARE_ANON_INHERITED_CLASS
966+
) {
963967
if (done_pass_two) {
964968
var = EX_VAR_TO_NUM(opline->result.var) - op_array->last_var;
965969
} else {
966970
var = opline->result.var;
967971
}
968-
/* Objects created via ZEND_NEW are only fully initialized after the DO_FCALL (constructor call) */
972+
ZEND_ASSERT(Tstart[var] == (unsigned) -1);
969973
if (opline->opcode == ZEND_NEW) {
974+
/* Objects created via ZEND_NEW are only fully initialized
975+
* after the DO_FCALL (constructor call) */
970976
Tstart[var] = opline->op2.opline_num - 1;
971977
} else {
972978
Tstart[var] = opline - op_array->opcodes;

0 commit comments

Comments
 (0)