]> granicus.if.org Git - php/commitdiff
Fix nullsafe operator on $this
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 11 Aug 2020 13:22:14 +0000 (15:22 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 11 Aug 2020 13:22:14 +0000 (15:22 +0200)
Zend/tests/nullsafe_operator/032.phpt [new file with mode: 0644]
Zend/zend_compile.c

diff --git a/Zend/tests/nullsafe_operator/032.phpt b/Zend/tests/nullsafe_operator/032.phpt
new file mode 100644 (file)
index 0000000..4718e66
--- /dev/null
@@ -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)
index 5e61760e9029e98c6b5af3987b704be24f17a745..9c4853ae4eb1149e50c8fd5d23359992f2a88620 100644 (file)
@@ -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);