summaryrefslogtreecommitdiff
path: root/Zend/zend_compile.c
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2016-04-08 01:41:48 +0200
committerNikita Popov <nikic@php.net>2016-04-27 17:10:44 +0200
commit4f54c15cb10dfd668538ae225fef59c82c66e96e (patch)
tree6592ba1551f755c16dab290f2e5fe5984b6637ca /Zend/zend_compile.c
parent480c5ed2be6bbd6d8f7e55b33e77e141f9d9d08f (diff)
downloadphp-git-4f54c15cb10dfd668538ae225fef59c82c66e96e.tar.gz
Ct bind private/final $this method call args
The test covers two edge-cases wrt opcache support.
Diffstat (limited to 'Zend/zend_compile.c')
-rw-r--r--Zend/zend_compile.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index c99cb686bf..b1f5768db9 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -3674,6 +3674,7 @@ void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type) /* {{
znode obj_node, method_node;
zend_op *opline;
+ zend_function *fbc = NULL;
if (is_this_fetch(obj_ast)) {
obj_node.op_type = IS_UNUSED;
@@ -3697,7 +3698,20 @@ void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type) /* {{
SET_NODE(opline->op2, &method_node);
}
- zend_compile_call_common(result, args_ast, NULL);
+ /* Check if this calls a known method on $this */
+ if (opline->op1_type == IS_UNUSED && opline->op2_type == IS_CONST &&
+ CG(active_class_entry) && zend_is_scope_known()) {
+ zend_string *lcname = Z_STR_P(CT_CONSTANT(opline->op2) + 1);
+ fbc = zend_hash_find_ptr(&CG(active_class_entry)->function_table, lcname);
+
+ /* We only know the exact method that is being called if it is either private or final.
+ * Otherwise an overriding method in a child class may be called. */
+ if (fbc && !(fbc->common.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_FINAL))) {
+ fbc = NULL;
+ }
+ }
+
+ zend_compile_call_common(result, args_ast, fbc);
}
/* }}} */