summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-08-11 15:22:14 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-08-11 15:22:14 +0200
commit227f1f148104f192cd86226e53e1e6c595d41cae (patch)
tree6da023eb9fceb401b830eb7db53a03030b6e642a
parent42eda5160d53955ff35bfc5d776fb5a5ea1c992f (diff)
downloadphp-git-227f1f148104f192cd86226e53e1e6c595d41cae.tar.gz
Fix nullsafe operator on $this
-rw-r--r--Zend/tests/nullsafe_operator/032.phpt25
-rw-r--r--Zend/zend_compile.c20
2 files changed, 37 insertions, 8 deletions
diff --git a/Zend/tests/nullsafe_operator/032.phpt b/Zend/tests/nullsafe_operator/032.phpt
new file mode 100644
index 0000000000..4718e66f15
--- /dev/null
+++ b/Zend/tests/nullsafe_operator/032.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Nullsafe operator on $this
+--FILE--
+<?php
+
+class Test {
+ public $foo = 42;
+
+ public function method() {
+ var_dump($this?->foo);
+ var_dump($this?->bar());
+ }
+
+ public function bar() {
+ return 24;
+ }
+}
+
+$test = new Test;
+$test->method();
+
+?>
+--EXPECT--
+int(42)
+int(24)
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 5e61760e90..9c4853ae4e 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2788,14 +2788,16 @@ static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t
zend_emit_op(&obj_node, ZEND_FETCH_THIS, NULL, NULL);
}
CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS;
+
+ /* We will throw if $this doesn't exist, so there's no need to emit a JMP_NULL
+ * check for a nullsafe access. */
} else {
zend_short_circuiting_mark_inner(obj_ast);
opline = zend_delayed_compile_var(&obj_node, obj_ast, type, 0);
zend_separate_if_call_and_write(&obj_node, obj_ast, type);
- }
-
- if (nullsafe) {
- zend_emit_jmp_null(&obj_node);
+ if (nullsafe) {
+ zend_emit_jmp_null(&obj_node);
+ }
}
zend_compile_expr(&prop_node, prop_ast);
@@ -4347,13 +4349,15 @@ void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type) /* {{
zend_emit_op(&obj_node, ZEND_FETCH_THIS, NULL, NULL);
}
CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS;
+
+ /* We will throw if $this doesn't exist, so there's no need to emit a JMP_NULL
+ * check for a nullsafe access. */
} else {
zend_short_circuiting_mark_inner(obj_ast);
zend_compile_expr(&obj_node, obj_ast);
- }
-
- if (nullsafe) {
- zend_emit_jmp_null(&obj_node);
+ if (nullsafe) {
+ zend_emit_jmp_null(&obj_node);
+ }
}
zend_compile_expr(&method_node, method_ast);