Skip to content

Commit bb8f4b3

Browse files
committed
fixup! Support first-class callables in const-expressions
1 parent deb2219 commit bb8f4b3

File tree

5 files changed

+29
-7
lines changed

5 files changed

+29
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
FCC in initializer errors for static reference to instance method.
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
public function myMethod(string $foo) {
8+
echo "Called ", __METHOD__, PHP_EOL;
9+
var_dump($foo);
10+
}
11+
}
12+
13+
const Closure = Foo::myMethod(...);
14+
15+
var_dump(Closure);
16+
(Closure)("abc");
17+
18+
?>
19+
--EXPECTF--
20+
Fatal error: Uncaught Error: Non-static method Foo::myMethod() cannot be called statically in %s:%d
21+
Stack trace:
22+
#0 {main}
23+
thrown in %s on line %d

Zend/zend_ast.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner(
10171017
zend_string *method_name = zend_ast_get_str(ast->child[1]);
10181018
fptr = zend_hash_find_ptr_lc(&ce->function_table, method_name);
10191019
if (!fptr) {
1020-
zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), ZSTR_VAL(method_name));
1020+
zend_undefined_method(ce, method_name);
10211021
return FAILURE;
10221022
}
10231023
if (!(fptr->common.fn_flags & ZEND_ACC_PUBLIC)) {
@@ -1034,6 +1034,9 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner(
10341034
}
10351035
}
10361036
}
1037+
if (!(fptr->common.fn_flags & ZEND_ACC_STATIC)) {
1038+
zend_non_static_method_call(fptr);
1039+
}
10371040
break;
10381041
}
10391042
}

Zend/zend_execute.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2443,7 +2443,7 @@ ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_index_write(HashTable *ht,
24432443
return retval;
24442444
}
24452445

2446-
static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_undefined_method(const zend_class_entry *ce, const zend_string *method)
2446+
ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_undefined_method(const zend_class_entry *ce, const zend_string *method)
24472447
{
24482448
zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), ZSTR_VAL(method));
24492449
}

Zend/zend_execute.h

+1
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ ZEND_API void zend_cleanup_unfinished_execution(zend_execute_data *execute_data,
436436
ZEND_API ZEND_ATTRIBUTE_DEPRECATED HashTable *zend_unfinished_execution_gc(zend_execute_data *execute_data, zend_execute_data *call, zend_get_gc_buffer *gc_buffer);
437437
ZEND_API HashTable *zend_unfinished_execution_gc_ex(zend_execute_data *execute_data, zend_execute_data *call, zend_get_gc_buffer *gc_buffer, bool suspended_by_yield);
438438
ZEND_API zval* ZEND_FASTCALL zend_fetch_static_property(zend_execute_data *ex, int fetch_type);
439+
ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_undefined_method(const zend_class_entry *ce, const zend_string *method);
439440
ZEND_API void ZEND_FASTCALL zend_non_static_method_call(const zend_function *fbc);
440441

441442
ZEND_API void zend_frameless_observed_call(zend_execute_data *execute_data);

ext/opcache/jit/zend_jit_helpers.c

-5
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,6 @@ static ZEND_COLD void ZEND_FASTCALL zend_jit_invalid_method_call_tmp(zval *objec
122122
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
123123
}
124124

125-
static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_undefined_method(const zend_class_entry *ce, const zend_string *method)
126-
{
127-
zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), ZSTR_VAL(method));
128-
}
129-
130125
static void ZEND_FASTCALL zend_jit_unref_helper(zval *zv)
131126
{
132127
zend_reference *ref;

0 commit comments

Comments
 (0)