]> granicus.if.org Git - php/commitdiff
BIND_STATIC of implicit binding may be undef
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 27 May 2019 15:11:44 +0000 (17:11 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 27 May 2019 15:12:20 +0000 (17:12 +0200)
Even though we don't need it at runtime, add the BIND_IMPLICIT
flag to BIND_STATIC as well, so we can distinguish this case in
type inference.

This fixes a JIT miscompile in arrow_functions/002.phpt.

Zend/zend_compile.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/opcache/Optimizer/zend_inference.c

index d0d5c7af1937dddbac8e472388eb4e4ca0f2576d..b4d4012d7f2e021c99d3487ca20348ba8fd14a49 100644 (file)
@@ -4012,7 +4012,7 @@ void zend_compile_global_var(zend_ast *ast) /* {{{ */
 }
 /* }}} */
 
-static void zend_compile_static_var_common(zend_string *var_name, zval *value, uint32_t by_ref) /* {{{ */
+static void zend_compile_static_var_common(zend_string *var_name, zval *value, uint32_t mode) /* {{{ */
 {
        zend_op *opline;
        if (!CG(active_op_array)->static_variables) {
@@ -4031,7 +4031,7 @@ static void zend_compile_static_var_common(zend_string *var_name, zval *value, u
        opline = zend_emit_op(NULL, ZEND_BIND_STATIC, NULL, NULL);
        opline->op1_type = IS_CV;
        opline->op1.var = lookup_cv(var_name);
-       opline->extended_value = (uint32_t)((char*)value - (char*)CG(active_op_array)->static_variables->arData) | by_ref;
+       opline->extended_value = (uint32_t)((char*)value - (char*)CG(active_op_array)->static_variables->arData) | mode;
 }
 /* }}} */
 
@@ -5584,7 +5584,7 @@ static void zend_compile_closure_uses(zend_ast *ast) /* {{{ */
                        }
                }
 
-               zend_compile_static_var_common(var_name, &zv, var_ast->attr);
+               zend_compile_static_var_common(var_name, &zv, var_ast->attr ? ZEND_BIND_REF : 0);
        }
 }
 /* }}} */
@@ -5595,7 +5595,7 @@ static void zend_compile_implicit_closure_uses(closure_info *info)
        ZEND_HASH_FOREACH_STR_KEY(&info->uses, var_name)
                zval zv;
                ZVAL_NULL(&zv);
-               zend_compile_static_var_common(var_name, &zv, 0);
+               zend_compile_static_var_common(var_name, &zv, ZEND_BIND_IMPLICIT);
        ZEND_HASH_FOREACH_END();
 }
 
index 8fae94fc494f99b8c8cda1927c3f6b7089655d8f..50ce8c1e9299c944c06c024f1cc7bc03b1a89f69 100644 (file)
@@ -8220,7 +8220,7 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, UNUSED, REF)
                ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht);
        }
 
-       value = (zval*)((char*)ht->arData + (opline->extended_value & ~ZEND_BIND_REF));
+       value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT)));
 
        if (opline->extended_value & ZEND_BIND_REF) {
                if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
index fbcd28de38f99310e8bf8fac0eb3ff9cd06f88fd..26bd027f3fc4ba8052022ca5334cba73514e207b 100644 (file)
@@ -50848,7 +50848,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_UNUSED_HAN
                ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht);
        }
 
-       value = (zval*)((char*)ht->arData + (opline->extended_value & ~ZEND_BIND_REF));
+       value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT)));
 
        if (opline->extended_value & ZEND_BIND_REF) {
                if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
index d6e3b4fa0da15b58475e31041f19003f35395b6a..866cfd06bb6b89da843b02a7d18b15bcc3ab9064 100644 (file)
@@ -3025,6 +3025,9 @@ static int zend_update_type_info(const zend_op_array *op_array,
                case ZEND_BIND_STATIC:
                        tmp = MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF
                                | ((opline->extended_value & ZEND_BIND_REF) ? MAY_BE_REF : (MAY_BE_RC1 | MAY_BE_RCN));
+                       if (opline->extended_value & ZEND_BIND_IMPLICIT) {
+                               tmp |= MAY_BE_UNDEF;
+                       }
                        UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
                        break;
                case ZEND_SEND_VAR: