Skip to content

Commit 7e565da

Browse files
committed
Fix incorrect use chain unlink
This issue has been introduced in 87ea3c1, where an || has been misinterpreted as an &&.
1 parent b41bd91 commit 7e565da

File tree

2 files changed

+82
-70
lines changed

2 files changed

+82
-70
lines changed

Zend/Optimizer/dfa_pass.c

Lines changed: 71 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,83 +1321,84 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
13211321
// op_2: #src_var.T = OP ... => #v.CV = OP ...
13221322
// op_1: QM_ASSIGN #src_var.T #orig_var.CV [undef,scalar] -> #v.CV, NOP
13231323

1324-
if (orig_var < 0) {
1324+
if (orig_var >= 0) {
13251325
zend_ssa_unlink_use_chain(ssa, op_1, orig_var);
1326-
/* Reconstruct SSA */
1327-
ssa->vars[v].definition = op_2;
1328-
ssa->ops[op_2].result_def = v;
1329-
1330-
ssa->vars[src_var].definition = -1;
1331-
ssa->vars[src_var].use_chain = -1;
1332-
1333-
ssa->ops[op_1].op1_use = -1;
1334-
ssa->ops[op_1].op1_def = -1;
1335-
ssa->ops[op_1].op1_use_chain = -1;
1336-
ssa->ops[op_1].result_use = -1;
1337-
ssa->ops[op_1].result_def = -1;
1338-
ssa->ops[op_1].res_use_chain = -1;
1339-
1340-
/* Update opcodes */
1341-
op_array->opcodes[op_2].result_type = opline->result_type;
1342-
op_array->opcodes[op_2].result.var = opline->result.var;
1343-
1344-
MAKE_NOP(opline);
1345-
remove_nops = 1;
1346-
1347-
if (op_array->opcodes[op_2].opcode == ZEND_SUB
1348-
&& op_array->opcodes[op_2].op1_type == op_array->opcodes[op_2].result_type
1349-
&& op_array->opcodes[op_2].op1.var == op_array->opcodes[op_2].result.var
1350-
&& op_array->opcodes[op_2].op2_type == IS_CONST
1351-
&& Z_TYPE_P(CT_CONSTANT_EX(op_array, op_array->opcodes[op_2].op2.constant)) == IS_LONG
1352-
&& Z_LVAL_P(CT_CONSTANT_EX(op_array, op_array->opcodes[op_2].op2.constant)) == 1
1353-
&& ssa->ops[op_2].op1_use >= 0
1354-
&& !(ssa->var_info[ssa->ops[op_2].op1_use].type & (MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) {
1326+
}
13551327

1356-
op_array->opcodes[op_2].opcode = ZEND_PRE_DEC;
1357-
SET_UNUSED(op_array->opcodes[op_2].op2);
1358-
SET_UNUSED(op_array->opcodes[op_2].result);
1328+
/* Reconstruct SSA */
1329+
ssa->vars[v].definition = op_2;
1330+
ssa->ops[op_2].result_def = v;
13591331

1360-
ssa->ops[op_2].result_def = -1;
1361-
ssa->ops[op_2].op1_def = v;
1332+
ssa->vars[src_var].definition = -1;
1333+
ssa->vars[src_var].use_chain = -1;
13621334

1363-
} else if (op_array->opcodes[op_2].opcode == ZEND_ADD
1364-
&& op_array->opcodes[op_2].op1_type == op_array->opcodes[op_2].result_type
1365-
&& op_array->opcodes[op_2].op1.var == op_array->opcodes[op_2].result.var
1366-
&& op_array->opcodes[op_2].op2_type == IS_CONST
1367-
&& Z_TYPE_P(CT_CONSTANT_EX(op_array, op_array->opcodes[op_2].op2.constant)) == IS_LONG
1368-
&& Z_LVAL_P(CT_CONSTANT_EX(op_array, op_array->opcodes[op_2].op2.constant)) == 1
1369-
&& ssa->ops[op_2].op1_use >= 0
1370-
&& !(ssa->var_info[ssa->ops[op_2].op1_use].type & (MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) {
1371-
1372-
op_array->opcodes[op_2].opcode = ZEND_PRE_INC;
1373-
SET_UNUSED(op_array->opcodes[op_2].op2);
1374-
SET_UNUSED(op_array->opcodes[op_2].result);
1375-
1376-
ssa->ops[op_2].result_def = -1;
1377-
ssa->ops[op_2].op1_def = v;
1335+
ssa->ops[op_1].op1_use = -1;
1336+
ssa->ops[op_1].op1_def = -1;
1337+
ssa->ops[op_1].op1_use_chain = -1;
1338+
ssa->ops[op_1].result_use = -1;
1339+
ssa->ops[op_1].result_def = -1;
1340+
ssa->ops[op_1].res_use_chain = -1;
13781341

1379-
} else if (op_array->opcodes[op_2].opcode == ZEND_ADD
1380-
&& op_array->opcodes[op_2].op2_type == op_array->opcodes[op_2].result_type
1381-
&& op_array->opcodes[op_2].op2.var == op_array->opcodes[op_2].result.var
1382-
&& op_array->opcodes[op_2].op1_type == IS_CONST
1383-
&& Z_TYPE_P(CT_CONSTANT_EX(op_array, op_array->opcodes[op_2].op1.constant)) == IS_LONG
1384-
&& Z_LVAL_P(CT_CONSTANT_EX(op_array, op_array->opcodes[op_2].op1.constant)) == 1
1385-
&& ssa->ops[op_2].op2_use >= 0
1386-
&& !(ssa->var_info[ssa->ops[op_2].op2_use].type & (MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) {
1342+
/* Update opcodes */
1343+
op_array->opcodes[op_2].result_type = opline->result_type;
1344+
op_array->opcodes[op_2].result.var = opline->result.var;
13871345

1388-
op_array->opcodes[op_2].opcode = ZEND_PRE_INC;
1389-
op_array->opcodes[op_2].op1_type = op_array->opcodes[op_2].op2_type;
1390-
op_array->opcodes[op_2].op1.var = op_array->opcodes[op_2].op2.var;
1391-
SET_UNUSED(op_array->opcodes[op_2].op2);
1392-
SET_UNUSED(op_array->opcodes[op_2].result);
1346+
MAKE_NOP(opline);
1347+
remove_nops = 1;
13931348

1394-
ssa->ops[op_2].result_def = -1;
1395-
ssa->ops[op_2].op1_def = v;
1396-
ssa->ops[op_2].op1_use = ssa->ops[op_2].op2_use;
1397-
ssa->ops[op_2].op1_use_chain = ssa->ops[op_2].op2_use_chain;
1398-
ssa->ops[op_2].op2_use = -1;
1399-
ssa->ops[op_2].op2_use_chain = -1;
1400-
}
1349+
if (op_array->opcodes[op_2].opcode == ZEND_SUB
1350+
&& op_array->opcodes[op_2].op1_type == op_array->opcodes[op_2].result_type
1351+
&& op_array->opcodes[op_2].op1.var == op_array->opcodes[op_2].result.var
1352+
&& op_array->opcodes[op_2].op2_type == IS_CONST
1353+
&& Z_TYPE_P(CT_CONSTANT_EX(op_array, op_array->opcodes[op_2].op2.constant)) == IS_LONG
1354+
&& Z_LVAL_P(CT_CONSTANT_EX(op_array, op_array->opcodes[op_2].op2.constant)) == 1
1355+
&& ssa->ops[op_2].op1_use >= 0
1356+
&& !(ssa->var_info[ssa->ops[op_2].op1_use].type & (MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) {
1357+
1358+
op_array->opcodes[op_2].opcode = ZEND_PRE_DEC;
1359+
SET_UNUSED(op_array->opcodes[op_2].op2);
1360+
SET_UNUSED(op_array->opcodes[op_2].result);
1361+
1362+
ssa->ops[op_2].result_def = -1;
1363+
ssa->ops[op_2].op1_def = v;
1364+
1365+
} else if (op_array->opcodes[op_2].opcode == ZEND_ADD
1366+
&& op_array->opcodes[op_2].op1_type == op_array->opcodes[op_2].result_type
1367+
&& op_array->opcodes[op_2].op1.var == op_array->opcodes[op_2].result.var
1368+
&& op_array->opcodes[op_2].op2_type == IS_CONST
1369+
&& Z_TYPE_P(CT_CONSTANT_EX(op_array, op_array->opcodes[op_2].op2.constant)) == IS_LONG
1370+
&& Z_LVAL_P(CT_CONSTANT_EX(op_array, op_array->opcodes[op_2].op2.constant)) == 1
1371+
&& ssa->ops[op_2].op1_use >= 0
1372+
&& !(ssa->var_info[ssa->ops[op_2].op1_use].type & (MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) {
1373+
1374+
op_array->opcodes[op_2].opcode = ZEND_PRE_INC;
1375+
SET_UNUSED(op_array->opcodes[op_2].op2);
1376+
SET_UNUSED(op_array->opcodes[op_2].result);
1377+
1378+
ssa->ops[op_2].result_def = -1;
1379+
ssa->ops[op_2].op1_def = v;
1380+
1381+
} else if (op_array->opcodes[op_2].opcode == ZEND_ADD
1382+
&& op_array->opcodes[op_2].op2_type == op_array->opcodes[op_2].result_type
1383+
&& op_array->opcodes[op_2].op2.var == op_array->opcodes[op_2].result.var
1384+
&& op_array->opcodes[op_2].op1_type == IS_CONST
1385+
&& Z_TYPE_P(CT_CONSTANT_EX(op_array, op_array->opcodes[op_2].op1.constant)) == IS_LONG
1386+
&& Z_LVAL_P(CT_CONSTANT_EX(op_array, op_array->opcodes[op_2].op1.constant)) == 1
1387+
&& ssa->ops[op_2].op2_use >= 0
1388+
&& !(ssa->var_info[ssa->ops[op_2].op2_use].type & (MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) {
1389+
1390+
op_array->opcodes[op_2].opcode = ZEND_PRE_INC;
1391+
op_array->opcodes[op_2].op1_type = op_array->opcodes[op_2].op2_type;
1392+
op_array->opcodes[op_2].op1.var = op_array->opcodes[op_2].op2.var;
1393+
SET_UNUSED(op_array->opcodes[op_2].op2);
1394+
SET_UNUSED(op_array->opcodes[op_2].result);
1395+
1396+
ssa->ops[op_2].result_def = -1;
1397+
ssa->ops[op_2].op1_def = v;
1398+
ssa->ops[op_2].op1_use = ssa->ops[op_2].op2_use;
1399+
ssa->ops[op_2].op1_use_chain = ssa->ops[op_2].op2_use_chain;
1400+
ssa->ops[op_2].op2_use = -1;
1401+
ssa->ops[op_2].op2_use_chain = -1;
14011402
}
14021403
}
14031404
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Don't try to unlink use chain of QM_ASSIGN without result use
3+
--FILE--
4+
<?php
5+
function test($arg) {
6+
var_dump(((int)$arg)-0);
7+
}
8+
test(1);
9+
?>
10+
--EXPECT--
11+
int(1)

0 commit comments

Comments
 (0)