diff --git a/Zend/tests/gh17222.phpt b/Zend/tests/gh17222.phpt new file mode 100644 index 0000000000000..1ef920c6119cd --- /dev/null +++ b/Zend/tests/gh17222.phpt @@ -0,0 +1,45 @@ +--TEST-- +GH-17222: __PROPERTY__ does not work in all constant expression contexts +--FILE-- +i; + } + set (#[MyAttr(msg: __PROPERTY__)] string $v) { + $this->i = $v; + } + } +} + +$f = new Foo(); +var_dump($f->i); + +$r = new ReflectionClass(Foo::class); +$p = $r->getProperty('i'); +var_dump($p->getAttributes()[0]->getArguments()['msg']); + +$get = $p->getHook(PropertyHookType::Get); +var_dump($get->getAttributes()[0]->getArguments()['msg']); + +$set = $p->getHook(PropertyHookType::Set); +var_dump($set->getParameters()[0]->getAttributes()[0]->getArguments()['msg']); + +?> +--EXPECT-- +string(1) "i" +string(1) "i" +string(1) "i" +string(1) "i" +string(1) "i" diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 456c0b8f410b4..d285bb0653ef3 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -8634,6 +8634,13 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f zend_type type = ZEND_TYPE_INIT_NONE(0); flags |= zend_property_is_virtual(ce, name, hooks_ast, flags) ? ZEND_ACC_VIRTUAL : 0; + /* FIXME: This is a dirty fix to maintain ABI compatibility. We don't + * have an actual property info yet, but we really only need the name + * anyway. We should convert this to a zend_string. */ + ZEND_ASSERT(!CG(context).active_property_info); + zend_property_info dummy_prop_info = { .name = name }; + CG(context).active_property_info = &dummy_prop_info; + if (!hooks_ast) { if (ce->ce_flags & ZEND_ACC_INTERFACE) { zend_error_noreturn(E_COMPILE_ERROR, @@ -8726,6 +8733,8 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f if (attr_ast) { zend_compile_attributes(&info->attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_PROPERTY, 0); } + + CG(context).active_property_info = NULL; } } /* }}} */