@@ -1125,7 +1125,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
1125
1125
}
1126
1126
1127
1127
// TODO: move me to other function?
1128
- for (v = 0 ; v < ssa -> vars_count ; v ++ ) {
1128
+ for (v = 0 ; v < ssa -> vars_count && op_array -> function_name /*TODO*/ ; v ++ ) {
1129
1129
int var = ssa -> vars [v ].var ;
1130
1130
if (var >= op_array -> last_var ) {
1131
1131
continue ;
@@ -1155,14 +1155,15 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
1155
1155
fprintf (stderr , "OP1: %d (var=%d)\n" , ssa -> vars [ssa -> ops [next_use ].op1_def ].var , var );
1156
1156
}
1157
1157
#endif
1158
- /* Either there is no next use which is okay, or the next use is an assignment
1159
- * which overrides the previous value, which is also okay. */
1160
- if (next_use < 0
1161
- || (op_array -> opcodes [next_use ].opcode == ZEND_ASSIGN
1162
- && ssa -> ops [next_use ].op1_use == v
1163
- && ssa -> vars [v ].var == var
1164
- && zend_ssa_next_use (ssa -> ops , v , next_use ) < 0 )) {
1165
- //fprintf(stderr, "HELLO\n");
1158
+ /* The next use must be an assignment, and there should be no uses after that.
1159
+ * If there is no next use or the next use is not an assignment, then we cannot safely
1160
+ * perform the operation without a copy because the nullified value would be observable indirectly
1161
+ * through compact(), func_get_args(), ... */
1162
+ if (next_use >= 0
1163
+ && op_array -> opcodes [next_use ].opcode == ZEND_ASSIGN
1164
+ && ssa -> ops [next_use ].op1_use == v
1165
+ && ssa -> vars [v ].var == var
1166
+ && zend_ssa_next_use (ssa -> ops , v , next_use ) < 0 ) {
1166
1167
ZEND_ASSERT (op_array -> opcodes [use ].extended_value == 0 );
1167
1168
op_array -> opcodes [use ].extended_value = 1 ;
1168
1169
}
0 commit comments