mirror of
https://github.com/php/php-src.git
synced 2024-09-21 01:47:25 +00:00
RFC: Add #[\Deprecated]
Attribute (#11293)
see https://wiki.php.net/rfc/deprecated_attribute Co-authored-by: Tim Düsterhus <tim@tideways-gmbh.com> Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
This commit is contained in:
parent
8291e81c00
commit
72c874691b
1
NEWS
1
NEWS
@ -32,6 +32,7 @@ PHP NEWS
|
||||
(Julien Voisin)
|
||||
. Fixed bug GH-11928 (The --enable-re2c-cgoto doesn't add the -g flag).
|
||||
(Peter Kokot)
|
||||
. Added the #[\Deprecated] attribute. (beberlei, timwolla)
|
||||
|
||||
- Curl:
|
||||
. Deprecated the CURLOPT_BINARYTRANSFER constant. (divinity76)
|
||||
|
@ -213,6 +213,8 @@ PHP 8.4 UPGRADE NOTES
|
||||
they allow chaining method calls, property accesses, etc. without enclosing
|
||||
the expression in parentheses.
|
||||
RFC: https://wiki.php.net/rfc/new_without_parentheses
|
||||
. Added the #[\Deprecated] attribute.
|
||||
RFC: https://wiki.php.net/rfc/deprecated_attribute
|
||||
|
||||
- Curl:
|
||||
. curl_version() returns an additional feature_list value, which is an
|
||||
|
@ -78,7 +78,7 @@ static void zend_delete_call_instructions(zend_op_array *op_array, zend_op *opli
|
||||
static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_op *opline, zend_function *func)
|
||||
{
|
||||
if (func->type == ZEND_USER_FUNCTION
|
||||
&& !(func->op_array.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_HAS_TYPE_HINTS))
|
||||
&& !(func->op_array.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_HAS_TYPE_HINTS|ZEND_ACC_DEPRECATED))
|
||||
/* TODO: function copied from trait may be inconsistent ??? */
|
||||
&& !(func->op_array.fn_flags & (ZEND_ACC_TRAIT_CLONE))
|
||||
&& fcall->extended_value >= func->op_array.required_num_args
|
||||
|
43
Zend/tests/attributes/deprecated/class_constants/001.phpt
Normal file
43
Zend/tests/attributes/deprecated/class_constants/001.phpt
Normal file
@ -0,0 +1,43 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Class Constants.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Clazz {
|
||||
#[\Deprecated]
|
||||
public const TEST = 1;
|
||||
|
||||
#[\Deprecated()]
|
||||
public const TEST2 = 2;
|
||||
|
||||
#[\Deprecated("use Clazz::TEST instead")]
|
||||
public const TEST3 = 3;
|
||||
|
||||
#[\Deprecated]
|
||||
public const TEST4 = 4;
|
||||
|
||||
#[\Deprecated]
|
||||
public const TEST5 = 5;
|
||||
}
|
||||
|
||||
var_dump(Clazz::TEST);
|
||||
var_dump(Clazz::TEST2);
|
||||
var_dump(Clazz::TEST3);
|
||||
|
||||
var_dump(constant('Clazz::TEST4'));
|
||||
var_dump(defined('Clazz::TEST5'));
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Constant Clazz::TEST is deprecated in %s on line %d
|
||||
int(1)
|
||||
|
||||
Deprecated: Constant Clazz::TEST2 is deprecated in %s on line %d
|
||||
int(2)
|
||||
|
||||
Deprecated: Constant Clazz::TEST3 is deprecated, use Clazz::TEST instead in %s on line %d
|
||||
int(3)
|
||||
|
||||
Deprecated: Constant Clazz::TEST4 is deprecated in %s on line %d
|
||||
int(4)
|
||||
bool(true)
|
21
Zend/tests/attributes/deprecated/class_constants/101.phpt
Normal file
21
Zend/tests/attributes/deprecated/class_constants/101.phpt
Normal file
@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Enum Cases.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
enum E {
|
||||
#[\Deprecated]
|
||||
case Test;
|
||||
|
||||
#[\Deprecated("use E::Test instead")]
|
||||
case Test2;
|
||||
}
|
||||
|
||||
E::Test;
|
||||
E::Test2;
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Enum case E::Test is deprecated in %s on line %d
|
||||
|
||||
Deprecated: Enum case E::Test2 is deprecated, use E::Test instead in %s on line %d
|
@ -0,0 +1,26 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Using the value of a deprecated class constant as the deprecation message.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Clazz {
|
||||
#[\Deprecated(self::TEST)]
|
||||
public const TEST = "from itself";
|
||||
|
||||
#[\Deprecated]
|
||||
public const TEST2 = "from another";
|
||||
|
||||
#[\Deprecated(self::TEST2)]
|
||||
public const TEST3 = 1;
|
||||
}
|
||||
|
||||
Clazz::TEST;
|
||||
Clazz::TEST3;
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Constant Clazz::TEST is deprecated, from itself in %s on line %d
|
||||
|
||||
Deprecated: Constant Clazz::TEST2 is deprecated in %s on line %d
|
||||
|
||||
Deprecated: Constant Clazz::TEST3 is deprecated, from another in %s on line %d
|
@ -0,0 +1,36 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Using the value of a deprecated class constant as the deprecation message with a throwing error handler.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
set_error_handler(function (int $errno, string $errstr, ?string $errfile = null, ?int $errline = null) {
|
||||
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
|
||||
});
|
||||
|
||||
class Clazz {
|
||||
#[\Deprecated(self::TEST)]
|
||||
public const TEST = "from itself";
|
||||
|
||||
#[\Deprecated]
|
||||
public const TEST2 = "from another";
|
||||
|
||||
#[\Deprecated(self::TEST2)]
|
||||
public const TEST3 = 1;
|
||||
}
|
||||
|
||||
try {
|
||||
Clazz::TEST;
|
||||
} catch (ErrorException $e) {
|
||||
echo "Caught: ", $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
try {
|
||||
Clazz::TEST3;
|
||||
} catch (ErrorException $e) {
|
||||
echo "Caught: ", $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Caught: Constant Clazz::TEST is deprecated, from itself
|
||||
Caught: Constant Clazz::TEST2 is deprecated
|
@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Using the value of a deprecated class constant in a constant expression.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Clazz {
|
||||
#[\Deprecated("prefix")]
|
||||
public const PREFIX = "prefix";
|
||||
|
||||
#[\Deprecated("suffix")]
|
||||
public const SUFFIX = "suffix";
|
||||
|
||||
public const CONSTANT = self::PREFIX . self::SUFFIX;
|
||||
}
|
||||
|
||||
var_dump(Clazz::CONSTANT);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Constant Clazz::PREFIX is deprecated, prefix in %s on line %d
|
||||
|
||||
Deprecated: Constant Clazz::SUFFIX is deprecated, suffix in %s on line %d
|
||||
string(12) "prefixsuffix"
|
@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Code is E_USER_DEPRECATED for class constants.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
set_error_handler(function (int $errno, string $errstr, ?string $errfile = null, ?int $errline = null) {
|
||||
var_dump($errno, E_USER_DEPRECATED, $errno === E_USER_DEPRECATED);
|
||||
});
|
||||
|
||||
class Clazz {
|
||||
#[\Deprecated]
|
||||
public const TEST = 1;
|
||||
}
|
||||
|
||||
Clazz::TEST;
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(16384)
|
||||
int(16384)
|
||||
bool(true)
|
@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Class constant with value unknown at compile time.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
define('SUFFIX', random_int(1, 2) == 1 ? 'a' : 'b');
|
||||
|
||||
class Clazz {
|
||||
#[\Deprecated]
|
||||
public const CONSTANT = self::class . '-' . SUFFIX;
|
||||
}
|
||||
|
||||
$value = Clazz::CONSTANT;
|
||||
var_dump($value);
|
||||
var_dump($value === 'Clazz-' . SUFFIX);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Constant Clazz::CONSTANT is deprecated in %s on line %d
|
||||
string(7) "Clazz-%c"
|
||||
bool(true)
|
76
Zend/tests/attributes/deprecated/functions/001.phpt
Normal file
76
Zend/tests/attributes/deprecated/functions/001.phpt
Normal file
@ -0,0 +1,76 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Functions and Methods.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
#[\Deprecated]
|
||||
function test() {
|
||||
}
|
||||
|
||||
#[\Deprecated("use test() instead")]
|
||||
function test2() {
|
||||
}
|
||||
|
||||
class Clazz {
|
||||
#[\Deprecated]
|
||||
function test() {
|
||||
}
|
||||
|
||||
#[\Deprecated("use test() instead")]
|
||||
function test2() {
|
||||
}
|
||||
}
|
||||
|
||||
$closure = #[\Deprecated] function() {
|
||||
};
|
||||
|
||||
$closure2 = #[\Deprecated] function() {
|
||||
};
|
||||
|
||||
class Constructor {
|
||||
#[\Deprecated]
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
#[\Deprecated]
|
||||
public function __destruct() {
|
||||
}
|
||||
}
|
||||
|
||||
test();
|
||||
test2();
|
||||
call_user_func("test");
|
||||
|
||||
$cls = new Clazz();
|
||||
$cls->test();
|
||||
$cls->test2();
|
||||
|
||||
call_user_func([$cls, "test"]);
|
||||
|
||||
$closure();
|
||||
|
||||
$closure2();
|
||||
|
||||
new Constructor();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Function test() is deprecated in %s
|
||||
|
||||
Deprecated: Function test2() is deprecated, use test() instead in %s on line %d
|
||||
|
||||
Deprecated: Function test() is deprecated in %s on line %d
|
||||
|
||||
Deprecated: Method Clazz::test() is deprecated in %s
|
||||
|
||||
Deprecated: Method Clazz::test2() is deprecated, use test() instead in %s
|
||||
|
||||
Deprecated: Method Clazz::test() is deprecated in %s
|
||||
|
||||
Deprecated: Function {closure:%s:%d}() is deprecated in %s on line %d
|
||||
|
||||
Deprecated: Function {closure:%s:%d}() is deprecated in %s on line %d
|
||||
|
||||
Deprecated: Method Constructor::__construct() is deprecated in %s on line %d
|
||||
|
||||
Deprecated: Method Constructor::__destruct() is deprecated in %s on line %d
|
@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Exception Handler is deprecated.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
#[\Deprecated]
|
||||
function my_exception_handler($e) {
|
||||
echo "Handled: ", $e->getMessage(), PHP_EOL;
|
||||
};
|
||||
|
||||
set_exception_handler('my_exception_handler');
|
||||
|
||||
throw new \Exception('test');
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Deprecated: Function my_exception_handler() is deprecated in Unknown on line 0
|
||||
Handled: test
|
@ -0,0 +1,31 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Exception Handler is deprecated for throwing error handler.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function my_error_handler(int $errno, string $errstr, ?string $errfile = null, ?int $errline = null) {
|
||||
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
|
||||
}
|
||||
|
||||
set_error_handler('my_error_handler');
|
||||
|
||||
#[\Deprecated]
|
||||
function my_exception_handler($e) {
|
||||
echo "Handled: ", $e->getMessage(), PHP_EOL;
|
||||
};
|
||||
|
||||
set_exception_handler('my_exception_handler');
|
||||
|
||||
#[\Deprecated]
|
||||
function test() {
|
||||
}
|
||||
|
||||
test();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught ErrorException: Function my_exception_handler() is deprecated in Unknown:0
|
||||
Stack trace:
|
||||
#0 [internal function]: my_error_handler(%d, '%s', '%s', %d)
|
||||
#1 {main}
|
||||
thrown in Unknown on line 0
|
@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Error Handler is deprecated.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
#[\Deprecated]
|
||||
function my_error_handler(int $errno, string $errstr, ?string $errfile = null, ?int $errline = null) {
|
||||
echo $errstr, PHP_EOL;
|
||||
};
|
||||
|
||||
set_error_handler('my_error_handler');
|
||||
|
||||
#[\Deprecated]
|
||||
function test() {
|
||||
}
|
||||
|
||||
test();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Function my_error_handler() is deprecated in %s on line %d
|
||||
Function test() is deprecated
|
@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Code is E_USER_DEPRECATED for functions.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
set_error_handler(function (int $errno, string $errstr, ?string $errfile = null, ?int $errline = null) {
|
||||
var_dump($errno, E_USER_DEPRECATED, $errno === E_USER_DEPRECATED);
|
||||
});
|
||||
|
||||
#[\Deprecated]
|
||||
function test() {
|
||||
}
|
||||
|
||||
test();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(16384)
|
||||
int(16384)
|
||||
bool(true)
|
16
Zend/tests/attributes/deprecated/functions/message_004.phpt
Normal file
16
Zend/tests/attributes/deprecated/functions/message_004.phpt
Normal file
@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Message from constant.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
#[\Deprecated(DEPRECATION_MESSAGE)]
|
||||
function test() {
|
||||
}
|
||||
|
||||
define('DEPRECATION_MESSAGE', 'from constant');
|
||||
|
||||
test();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Function test() is deprecated, from constant in %s on line %d
|
22
Zend/tests/attributes/deprecated/functions/message_005.phpt
Normal file
22
Zend/tests/attributes/deprecated/functions/message_005.phpt
Normal file
@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Message from protected class constant.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class P {
|
||||
protected const DEPRECATION_MESSAGE = 'from class constant';
|
||||
}
|
||||
|
||||
class Clazz extends P {
|
||||
#[\Deprecated(parent::DEPRECATION_MESSAGE)]
|
||||
public function test() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$c = new Clazz();
|
||||
$c->test();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Method Clazz::test() is deprecated, from class constant in %s on line %d
|
@ -0,0 +1,91 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Throwing error handler.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
set_error_handler(function (int $errno, string $errstr, ?string $errfile = null, ?int $errline = null) {
|
||||
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
|
||||
});
|
||||
|
||||
#[\Deprecated("convert to exception")]
|
||||
function test() {
|
||||
echo "Not executed", PHP_EOL;
|
||||
}
|
||||
|
||||
try {
|
||||
test();
|
||||
} catch (ErrorException $e) {
|
||||
echo "Caught: ", $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
eval(<<<'CODE'
|
||||
#[\Deprecated("convert to exception")]
|
||||
function test2() {
|
||||
echo "Not executed", PHP_EOL;
|
||||
}
|
||||
CODE);
|
||||
|
||||
try {
|
||||
test2();
|
||||
} catch (ErrorException $e) {
|
||||
echo "Caught: ", $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
class Clazz {
|
||||
#[\Deprecated("convert to exception")]
|
||||
function test() {
|
||||
echo "Not executed", PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$cls = new Clazz();
|
||||
$cls->test();
|
||||
} catch (ErrorException $e) {
|
||||
echo "Caught: ", $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
$closure = #[\Deprecated("convert to exception")] function () {
|
||||
echo "Not executed", PHP_EOL;
|
||||
};
|
||||
|
||||
try {
|
||||
$closure();
|
||||
} catch (ErrorException $e) {
|
||||
echo "Caught: ", $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
class Constructor {
|
||||
#[\Deprecated("convert to exception")]
|
||||
public function __construct() {
|
||||
echo "Not executed", PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
new Constructor();
|
||||
} catch (ErrorException $e) {
|
||||
echo "Caught: ", $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
class Destructor {
|
||||
#[\Deprecated("convert to exception")]
|
||||
public function __destruct() {
|
||||
echo "Not executed", PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
new Destructor();
|
||||
} catch (ErrorException $e) {
|
||||
echo "Caught: ", $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Caught: Function test() is deprecated, convert to exception
|
||||
Caught: Function test2() is deprecated, convert to exception
|
||||
Caught: Method Clazz::test() is deprecated, convert to exception
|
||||
Caught: Function {closure:%s:%d}() is deprecated, convert to exception
|
||||
Caught: Method Constructor::__construct() is deprecated, convert to exception
|
||||
Caught: Method Destructor::__destruct() is deprecated, convert to exception
|
@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Throwing error handler when using the return value.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
set_error_handler(function (int $errno, string $errstr, ?string $errfile = null, ?int $errline = null) {
|
||||
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
|
||||
});
|
||||
|
||||
#[Deprecated]
|
||||
function test() {}
|
||||
|
||||
try {
|
||||
$x = test();
|
||||
} catch (ErrorException $e) {
|
||||
echo "Caught: ", $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Caught: Function test() is deprecated
|
@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Throwing error handler does not leak parameters.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
set_error_handler(function (int $errno, string $errstr, ?string $errfile = null, ?int $errline = null) {
|
||||
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
|
||||
});
|
||||
|
||||
#[Deprecated]
|
||||
function test($dummy) {}
|
||||
|
||||
try {
|
||||
$x = test(new stdClass());
|
||||
} catch (ErrorException $e) {
|
||||
echo "Caught: ", $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Caught: Function test() is deprecated
|
49
Zend/tests/attributes/deprecated/message_001.phpt
Normal file
49
Zend/tests/attributes/deprecated/message_001.phpt
Normal file
@ -0,0 +1,49 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Message Formats.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
#[\Deprecated]
|
||||
function test1() {
|
||||
}
|
||||
|
||||
#[\Deprecated()]
|
||||
function test2() {
|
||||
}
|
||||
|
||||
#[\Deprecated("use test() instead")]
|
||||
function test3() {
|
||||
}
|
||||
|
||||
#[\Deprecated(message: "use test() instead", since: "1.0")]
|
||||
function test4() {
|
||||
}
|
||||
|
||||
#[\Deprecated(since: "1.0", message: "use test() instead")]
|
||||
function test5() {
|
||||
}
|
||||
|
||||
#[\Deprecated(since: "1.0")]
|
||||
function test6() {
|
||||
}
|
||||
|
||||
test1();
|
||||
test2();
|
||||
test3();
|
||||
test4();
|
||||
test5();
|
||||
test6();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Function test1() is deprecated in %s on line %d
|
||||
|
||||
Deprecated: Function test2() is deprecated in %s on line %d
|
||||
|
||||
Deprecated: Function test3() is deprecated, use test() instead in %s on line %d
|
||||
|
||||
Deprecated: Function test4() is deprecated since 1.0, use test() instead in %s on line %d
|
||||
|
||||
Deprecated: Function test5() is deprecated since 1.0, use test() instead in %s on line %d
|
||||
|
||||
Deprecated: Function test6() is deprecated since 1.0 in %s on line %d
|
14
Zend/tests/attributes/deprecated/message_002.phpt
Normal file
14
Zend/tests/attributes/deprecated/message_002.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Message is empty.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
#[\Deprecated("")]
|
||||
function test() {
|
||||
}
|
||||
|
||||
test();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Function test() is deprecated in %s on line %d
|
14
Zend/tests/attributes/deprecated/message_003.phpt
Normal file
14
Zend/tests/attributes/deprecated/message_003.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Message contains NUL bytes.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
#[\Deprecated("Here is a NUL \x00 Byte")]
|
||||
function test() {
|
||||
}
|
||||
|
||||
test();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Function test() is deprecated, Here is a NUL %0 Byte in %s on line %d
|
16
Zend/tests/attributes/deprecated/message_004.phpt
Normal file
16
Zend/tests/attributes/deprecated/message_004.phpt
Normal file
@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Message with value unknown at compile time.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
define('MESSAGE', 'value-' . (random_int(1, 2) == 1 ? 'a' : 'b'));
|
||||
|
||||
#[\Deprecated(MESSAGE)]
|
||||
function test() {
|
||||
}
|
||||
|
||||
test();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Function test() is deprecated, value-%c in %s on line %d
|
14
Zend/tests/attributes/deprecated/property_readonly_001.phpt
Normal file
14
Zend/tests/attributes/deprecated/property_readonly_001.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Deprecated::$message is readonly.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$d = new \Deprecated("foo");
|
||||
$d->message = 'bar';
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Cannot modify readonly property Deprecated::$message in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
14
Zend/tests/attributes/deprecated/property_readonly_002.phpt
Normal file
14
Zend/tests/attributes/deprecated/property_readonly_002.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Deprecated::$since is readonly.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$d = new \Deprecated("foo", "1.0");
|
||||
$d->since = "2.0";
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Cannot modify readonly property Deprecated::$since in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
15
Zend/tests/attributes/deprecated/property_readonly_003.phpt
Normal file
15
Zend/tests/attributes/deprecated/property_readonly_003.phpt
Normal file
@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: __construct() respects that properties are readonly.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$d = new \Deprecated("foo");
|
||||
$d->__construct("bar");
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Cannot modify readonly property Deprecated::$message in %s:%d
|
||||
Stack trace:
|
||||
#0 %s(%d): Deprecated->__construct('bar')
|
||||
#1 {main}
|
||||
thrown in %s on line %d
|
14
Zend/tests/attributes/deprecated/type_validation_001.phpt
Normal file
14
Zend/tests/attributes/deprecated/type_validation_001.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Type validation of $message parameter with int.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
#[\Deprecated(1234)]
|
||||
function test() {
|
||||
}
|
||||
|
||||
test();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Function test() is deprecated, 1234 in %s on line %d
|
19
Zend/tests/attributes/deprecated/type_validation_002.phpt
Normal file
19
Zend/tests/attributes/deprecated/type_validation_002.phpt
Normal file
@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Type validation of $message parameter with int and strict types.
|
||||
--FILE--
|
||||
<?php
|
||||
declare(strict_types = 1);
|
||||
|
||||
#[\Deprecated(1234)]
|
||||
function test() {
|
||||
}
|
||||
|
||||
test();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught TypeError: Deprecated::__construct(): Argument #1 ($message) must be of type ?string, int given in %s:%d
|
||||
Stack trace:
|
||||
#0 %s(%d): Deprecated->__construct(1234)
|
||||
#1 {main}
|
||||
thrown in %s on line %d
|
17
Zend/tests/attributes/deprecated/type_validation_003.phpt
Normal file
17
Zend/tests/attributes/deprecated/type_validation_003.phpt
Normal file
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Type validation of $message parameter with array.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
#[\Deprecated([])]
|
||||
function test() {
|
||||
}
|
||||
test();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught TypeError: Deprecated::__construct(): Argument #1 ($message) must be of type ?string, array given in %s:%d
|
||||
Stack trace:
|
||||
#0 %s(%d): Deprecated->__construct(Array)
|
||||
#1 {main}
|
||||
thrown in %s on line %d
|
17
Zend/tests/attributes/deprecated/type_validation_004.phpt
Normal file
17
Zend/tests/attributes/deprecated/type_validation_004.phpt
Normal file
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Type validation of $message parameter with native enum case.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
#[\Deprecated(\Random\IntervalBoundary::ClosedOpen)]
|
||||
function test() {
|
||||
}
|
||||
test();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught TypeError: Deprecated::__construct(): Argument #1 ($message) must be of type ?string, Random\IntervalBoundary given in %s:%d
|
||||
Stack trace:
|
||||
#0 %s(%d): Deprecated->__construct(Random\IntervalBoundary::ClosedOpen)
|
||||
#1 {main}
|
||||
thrown in %s on line %d
|
@ -30,6 +30,7 @@ ZEND_API zend_class_entry *zend_ce_allow_dynamic_properties;
|
||||
ZEND_API zend_class_entry *zend_ce_sensitive_parameter;
|
||||
ZEND_API zend_class_entry *zend_ce_sensitive_parameter_value;
|
||||
ZEND_API zend_class_entry *zend_ce_override;
|
||||
ZEND_API zend_class_entry *zend_ce_deprecated;
|
||||
|
||||
static zend_object_handlers attributes_object_handlers_sensitive_parameter_value;
|
||||
|
||||
@ -146,6 +147,43 @@ ZEND_METHOD(Override, __construct)
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
}
|
||||
|
||||
ZEND_METHOD(Deprecated, __construct)
|
||||
{
|
||||
zend_string *message = NULL;
|
||||
zend_string *since = NULL;
|
||||
zval value;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(0, 2)
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_STR_OR_NULL(message)
|
||||
Z_PARAM_STR_OR_NULL(since)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (message) {
|
||||
ZVAL_STR(&value, message);
|
||||
} else {
|
||||
ZVAL_NULL(&value);
|
||||
}
|
||||
zend_update_property_ex(zend_ce_deprecated, Z_OBJ_P(ZEND_THIS), ZSTR_KNOWN(ZEND_STR_MESSAGE), &value);
|
||||
|
||||
/* The assignment might fail due to 'readonly'. */
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
if (since) {
|
||||
ZVAL_STR(&value, since);
|
||||
} else {
|
||||
ZVAL_NULL(&value);
|
||||
}
|
||||
zend_update_property_ex(zend_ce_deprecated, Z_OBJ_P(ZEND_THIS), ZSTR_KNOWN(ZEND_STR_SINCE), &value);
|
||||
|
||||
/* The assignment might fail due to 'readonly'. */
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
}
|
||||
|
||||
static zend_attribute *get_attribute(HashTable *attributes, zend_string *lcname, uint32_t offset)
|
||||
{
|
||||
if (attributes) {
|
||||
@ -470,6 +508,9 @@ void zend_register_attribute_ce(void)
|
||||
|
||||
zend_ce_override = register_class_Override();
|
||||
zend_mark_internal_attribute(zend_ce_override);
|
||||
|
||||
zend_ce_deprecated = register_class_Deprecated();
|
||||
attr = zend_mark_internal_attribute(zend_ce_deprecated);
|
||||
}
|
||||
|
||||
void zend_attributes_shutdown(void)
|
||||
|
@ -46,6 +46,7 @@ extern ZEND_API zend_class_entry *zend_ce_allow_dynamic_properties;
|
||||
extern ZEND_API zend_class_entry *zend_ce_sensitive_parameter;
|
||||
extern ZEND_API zend_class_entry *zend_ce_sensitive_parameter_value;
|
||||
extern ZEND_API zend_class_entry *zend_ce_override;
|
||||
extern ZEND_API zend_class_entry *zend_ce_deprecated;
|
||||
|
||||
typedef struct {
|
||||
zend_string *name;
|
||||
|
@ -71,3 +71,16 @@ final class Override
|
||||
{
|
||||
public function __construct() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @strict-properties
|
||||
*/
|
||||
#[Attribute(Attribute::TARGET_METHOD|Attribute::TARGET_FUNCTION|Attribute::TARGET_CLASS_CONSTANT)]
|
||||
final class Deprecated
|
||||
{
|
||||
public readonly ?string $message;
|
||||
|
||||
public readonly ?string $since;
|
||||
|
||||
public function __construct(?string $message = null, ?string $since = null) {}
|
||||
}
|
||||
|
43
Zend/zend_attributes_arginfo.h
generated
43
Zend/zend_attributes_arginfo.h
generated
@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 32f0458c20f04099e353a8300ffb19e40bc38f69 */
|
||||
* Stub hash: 2358a0d820edd06a1702c84104bfd545af08311c */
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Attribute___construct, 0, 0, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "Attribute::TARGET_ALL")
|
||||
@ -24,6 +24,11 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_Override___construct arginfo_class_ReturnTypeWillChange___construct
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Deprecated___construct, 0, 0, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, message, IS_STRING, 1, "null")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, since, IS_STRING, 1, "null")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_METHOD(Attribute, __construct);
|
||||
ZEND_METHOD(ReturnTypeWillChange, __construct);
|
||||
ZEND_METHOD(AllowDynamicProperties, __construct);
|
||||
@ -32,6 +37,7 @@ ZEND_METHOD(SensitiveParameterValue, __construct);
|
||||
ZEND_METHOD(SensitiveParameterValue, getValue);
|
||||
ZEND_METHOD(SensitiveParameterValue, __debugInfo);
|
||||
ZEND_METHOD(Override, __construct);
|
||||
ZEND_METHOD(Deprecated, __construct);
|
||||
|
||||
static const zend_function_entry class_Attribute_methods[] = {
|
||||
ZEND_ME(Attribute, __construct, arginfo_class_Attribute___construct, ZEND_ACC_PUBLIC)
|
||||
@ -65,6 +71,11 @@ static const zend_function_entry class_Override_methods[] = {
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
static const zend_function_entry class_Deprecated_methods[] = {
|
||||
ZEND_ME(Deprecated, __construct, arginfo_class_Deprecated___construct, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
static zend_class_entry *register_class_Attribute(void)
|
||||
{
|
||||
zend_class_entry ce, *class_entry;
|
||||
@ -225,3 +236,33 @@ static zend_class_entry *register_class_Override(void)
|
||||
|
||||
return class_entry;
|
||||
}
|
||||
|
||||
static zend_class_entry *register_class_Deprecated(void)
|
||||
{
|
||||
zend_class_entry ce, *class_entry;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "Deprecated", class_Deprecated_methods);
|
||||
class_entry = zend_register_internal_class_ex(&ce, NULL);
|
||||
class_entry->ce_flags |= ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES;
|
||||
|
||||
zval property_message_default_value;
|
||||
ZVAL_UNDEF(&property_message_default_value);
|
||||
zend_string *property_message_name = zend_string_init("message", sizeof("message") - 1, 1);
|
||||
zend_declare_typed_property(class_entry, property_message_name, &property_message_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
|
||||
zend_string_release(property_message_name);
|
||||
|
||||
zval property_since_default_value;
|
||||
ZVAL_UNDEF(&property_since_default_value);
|
||||
zend_string *property_since_name = zend_string_init("since", sizeof("since") - 1, 1);
|
||||
zend_declare_typed_property(class_entry, property_since_name, &property_since_default_value, ZEND_ACC_PUBLIC|ZEND_ACC_READONLY, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_STRING|MAY_BE_NULL));
|
||||
zend_string_release(property_since_name);
|
||||
|
||||
zend_string *attribute_name_Attribute_class_Deprecated_0 = zend_string_init_interned("Attribute", sizeof("Attribute") - 1, 1);
|
||||
zend_attribute *attribute_Attribute_class_Deprecated_0 = zend_add_class_attribute(class_entry, attribute_name_Attribute_class_Deprecated_0, 1);
|
||||
zend_string_release(attribute_name_Attribute_class_Deprecated_0);
|
||||
zval attribute_Attribute_class_Deprecated_0_arg0;
|
||||
ZVAL_LONG(&attribute_Attribute_class_Deprecated_0_arg0, ZEND_ATTRIBUTE_TARGET_METHOD | ZEND_ATTRIBUTE_TARGET_FUNCTION | ZEND_ATTRIBUTE_TARGET_CLASS_CONST);
|
||||
ZVAL_COPY_VALUE(&attribute_Attribute_class_Deprecated_0->args[0].value, &attribute_Attribute_class_Deprecated_0_arg0);
|
||||
|
||||
return class_entry;
|
||||
}
|
||||
|
@ -3883,7 +3883,11 @@ ZEND_API uint8_t zend_get_call_op(const zend_op *init_op, zend_function *fbc) /*
|
||||
}
|
||||
} else if (!(CG(compiler_options) & ZEND_COMPILE_IGNORE_USER_FUNCTIONS)){
|
||||
if (zend_execute_ex == execute_ex) {
|
||||
return ZEND_DO_UCALL;
|
||||
if (!(fbc->common.fn_flags & ZEND_ACC_DEPRECATED)) {
|
||||
return ZEND_DO_UCALL;
|
||||
} else {
|
||||
return ZEND_DO_FCALL_BY_NAME;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (zend_execute_ex == execute_ex &&
|
||||
@ -8047,6 +8051,16 @@ static void zend_compile_func_decl(znode *result, zend_ast *ast, bool toplevel)
|
||||
if (override_attribute) {
|
||||
op_array->fn_flags |= ZEND_ACC_OVERRIDE;
|
||||
}
|
||||
|
||||
zend_attribute *deprecated_attribute = zend_get_attribute_str(
|
||||
op_array->attributes,
|
||||
"deprecated",
|
||||
sizeof("deprecated")-1
|
||||
);
|
||||
|
||||
if (deprecated_attribute) {
|
||||
op_array->fn_flags |= ZEND_ACC_DEPRECATED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do not leak the class scope into free standing functions, even if they are dynamically
|
||||
@ -8304,6 +8318,12 @@ static void zend_compile_class_const_decl(zend_ast *ast, uint32_t flags, zend_as
|
||||
|
||||
if (attr_ast) {
|
||||
zend_compile_attributes(&c->attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_CLASS_CONST, 0);
|
||||
|
||||
zend_attribute *deprecated = zend_get_attribute_str(c->attributes, "deprecated", sizeof("deprecated")-1);
|
||||
|
||||
if (deprecated) {
|
||||
ZEND_CLASS_CONST_FLAGS(c) |= ZEND_ACC_DEPRECATED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8733,6 +8753,12 @@ static void zend_compile_enum_case(zend_ast *ast)
|
||||
zend_ast *attr_ast = ast->child[3];
|
||||
if (attr_ast) {
|
||||
zend_compile_attributes(&c->attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_CLASS_CONST, 0);
|
||||
|
||||
zend_attribute *deprecated = zend_get_attribute_str(c->attributes, "deprecated", sizeof("deprecated")-1);
|
||||
|
||||
if (deprecated) {
|
||||
ZEND_CLASS_CONST_FLAGS(c) |= ZEND_ACC_DEPRECATED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -354,7 +354,7 @@ ZEND_API zval *zend_get_class_constant_ex(zend_string *class_name, zend_string *
|
||||
|
||||
if (UNEXPECTED(ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED)) {
|
||||
if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) {
|
||||
zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
|
||||
zend_deprecated_class_constant(c, constant_name);
|
||||
if (EG(exception)) {
|
||||
goto failure;
|
||||
}
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "zend_observer.h"
|
||||
#include "zend_system_id.h"
|
||||
#include "zend_call_stack.h"
|
||||
#include "zend_attributes.h"
|
||||
#include "Optimizer/zend_func_info.h"
|
||||
|
||||
/* Virtual current working directory support */
|
||||
@ -1766,16 +1767,118 @@ ZEND_API ZEND_COLD void zend_wrong_string_offset_error(void)
|
||||
zend_throw_error(NULL, "%s", msg);
|
||||
}
|
||||
|
||||
ZEND_COLD static zend_result ZEND_FASTCALL get_deprecation_suffix_from_attribute(HashTable *attributes, zend_class_entry* scope, zend_string **message_suffix)
|
||||
{
|
||||
*message_suffix = ZSTR_EMPTY_ALLOC();
|
||||
|
||||
if (!attributes) {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
zend_attribute *deprecated = zend_get_attribute_str(attributes, "deprecated", sizeof("deprecated")-1);
|
||||
|
||||
if (!deprecated) {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if (deprecated->argc == 0) {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
zend_result result = FAILURE;
|
||||
|
||||
zend_string *message = ZSTR_EMPTY_ALLOC();
|
||||
zend_string *since = ZSTR_EMPTY_ALLOC();
|
||||
|
||||
zval obj;
|
||||
ZVAL_UNDEF(&obj);
|
||||
zval *z;
|
||||
|
||||
/* Construct the Deprecated object to correctly handle parameter processing. */
|
||||
if (FAILURE == zend_get_attribute_object(&obj, zend_ce_deprecated, deprecated, scope, NULL)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Extract the $message property. */
|
||||
z = zend_read_property_ex(zend_ce_deprecated, Z_OBJ_P(&obj), ZSTR_KNOWN(ZEND_STR_MESSAGE), false, NULL);
|
||||
ZEND_ASSERT(z != &EG(uninitialized_zval));
|
||||
if (Z_TYPE_P(z) == IS_STRING) {
|
||||
message = zend_string_copy(Z_STR_P(z));
|
||||
}
|
||||
|
||||
/* Extract the $since property. */
|
||||
z = zend_read_property_ex(zend_ce_deprecated, Z_OBJ_P(&obj), ZSTR_KNOWN(ZEND_STR_SINCE), false, NULL);
|
||||
ZEND_ASSERT(z != &EG(uninitialized_zval));
|
||||
if (Z_TYPE_P(z) == IS_STRING) {
|
||||
since = zend_string_copy(Z_STR_P(z));
|
||||
}
|
||||
|
||||
/* Construct the suffix. */
|
||||
*message_suffix = zend_strpprintf_unchecked(
|
||||
0,
|
||||
"%s%S%s%S",
|
||||
ZSTR_LEN(since) > 0 ? " since " : "",
|
||||
since,
|
||||
ZSTR_LEN(message) > 0 ? ", " : "",
|
||||
message
|
||||
);
|
||||
|
||||
result = SUCCESS;
|
||||
|
||||
out:
|
||||
|
||||
zend_string_release(since);
|
||||
zend_string_release(message);
|
||||
zval_ptr_dtor(&obj);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_function(const zend_function *fbc)
|
||||
{
|
||||
zend_string *message_suffix = ZSTR_EMPTY_ALLOC();
|
||||
|
||||
if (get_deprecation_suffix_from_attribute(fbc->common.attributes, fbc->common.scope, &message_suffix) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
int code = fbc->type == ZEND_INTERNAL_FUNCTION ? E_DEPRECATED : E_USER_DEPRECATED;
|
||||
|
||||
if (fbc->common.scope) {
|
||||
zend_error(E_DEPRECATED, "Method %s::%s() is deprecated",
|
||||
zend_error_unchecked(code, "Method %s::%s() is deprecated%S",
|
||||
ZSTR_VAL(fbc->common.scope->name),
|
||||
ZSTR_VAL(fbc->common.function_name)
|
||||
ZSTR_VAL(fbc->common.function_name),
|
||||
message_suffix
|
||||
);
|
||||
} else {
|
||||
zend_error(E_DEPRECATED, "Function %s() is deprecated", ZSTR_VAL(fbc->common.function_name));
|
||||
zend_error_unchecked(code, "Function %s() is deprecated%S",
|
||||
ZSTR_VAL(fbc->common.function_name),
|
||||
message_suffix
|
||||
);
|
||||
}
|
||||
|
||||
zend_string_release(message_suffix);
|
||||
}
|
||||
|
||||
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_class_constant(const zend_class_constant *c, const zend_string *constant_name)
|
||||
{
|
||||
zend_string *message_suffix = ZSTR_EMPTY_ALLOC();
|
||||
|
||||
if (get_deprecation_suffix_from_attribute(c->attributes, c->ce, &message_suffix) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
int code = c->ce->type == ZEND_INTERNAL_CLASS ? E_DEPRECATED : E_USER_DEPRECATED;
|
||||
char *type = (ZEND_CLASS_CONST_FLAGS(c) & ZEND_CLASS_CONST_IS_CASE) ? "Enum case" : "Constant";
|
||||
|
||||
zend_error_unchecked(code, "%s %s::%s is deprecated%S",
|
||||
type,
|
||||
ZSTR_VAL(c->ce->name),
|
||||
ZSTR_VAL(constant_name),
|
||||
message_suffix
|
||||
);
|
||||
|
||||
zend_string_release(message_suffix);
|
||||
}
|
||||
|
||||
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_false_to_array_deprecated(void)
|
||||
|
@ -62,6 +62,7 @@ extern ZEND_API const zend_internal_function zend_pass_function;
|
||||
|
||||
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(zend_execute_data *execute_data);
|
||||
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_function(const zend_function *fbc);
|
||||
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_class_constant(const zend_class_constant *c, const zend_string *constant_name);
|
||||
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_false_to_array_deprecated(void);
|
||||
ZEND_COLD void ZEND_FASTCALL zend_param_must_be_ref(const zend_function *func, uint32_t arg_num);
|
||||
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_use_resource_as_offset(const zval *dim);
|
||||
|
@ -633,6 +633,8 @@ EMPTY_SWITCH_DEFAULT_CASE()
|
||||
_(ZEND_STR_COUNT, "count") \
|
||||
_(ZEND_STR_SENSITIVEPARAMETER, "SensitiveParameter") \
|
||||
_(ZEND_STR_CONST_EXPR_PLACEHOLDER, "[constant expression]") \
|
||||
_(ZEND_STR_DEPRECATED, "Deprecated") \
|
||||
_(ZEND_STR_SINCE, "since") \
|
||||
|
||||
|
||||
typedef enum _zend_known_string_id {
|
||||
|
@ -4072,10 +4072,23 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL,OBSERVER))
|
||||
zend_execute_data *call = EX(call);
|
||||
zend_function *fbc = call->func;
|
||||
zval *ret;
|
||||
zval retval;
|
||||
|
||||
SAVE_OPLINE();
|
||||
EX(call) = call->prev_execute_data;
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
UNDEF_RESULT();
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
ZEND_VM_C_GOTO(fcall_by_name_end);
|
||||
}
|
||||
}
|
||||
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
|
||||
ret = NULL;
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
@ -4091,24 +4104,11 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL,OBSERVER))
|
||||
|
||||
ZEND_VM_ENTER_EX();
|
||||
} else {
|
||||
zval retval;
|
||||
ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
|
||||
if (ZEND_OBSERVER_ENABLED) {
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
UNDEF_RESULT();
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
ZEND_VM_C_GOTO(fcall_by_name_end);
|
||||
}
|
||||
}
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
@ -4138,7 +4138,12 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL,OBSERVER))
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
|
||||
ZEND_VM_C_GOTO(fcall_by_name_end);
|
||||
}
|
||||
|
||||
if (0) {
|
||||
ZEND_VM_C_LABEL(fcall_by_name_end):
|
||||
|
||||
zend_vm_stack_free_args(call);
|
||||
|
||||
uint32_t call_info = ZEND_CALL_INFO(call);
|
||||
@ -4170,10 +4175,26 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
|
||||
zend_execute_data *call = EX(call);
|
||||
zend_function *fbc = call->func;
|
||||
zval *ret;
|
||||
zval retval;
|
||||
|
||||
SAVE_OPLINE();
|
||||
EX(call) = call->prev_execute_data;
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) {
|
||||
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func));
|
||||
}
|
||||
UNDEF_RESULT();
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
ZEND_VM_C_GOTO(fcall_end);
|
||||
}
|
||||
}
|
||||
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
|
||||
ret = NULL;
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
@ -4198,24 +4219,11 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
|
||||
zend_execute_ex(call);
|
||||
}
|
||||
} else {
|
||||
zval retval;
|
||||
ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
|
||||
if (ZEND_OBSERVER_ENABLED) {
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
UNDEF_RESULT();
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
ZEND_VM_C_GOTO(fcall_end);
|
||||
}
|
||||
}
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
@ -4250,7 +4258,12 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
|
||||
ZEND_VM_C_GOTO(fcall_end);
|
||||
}
|
||||
|
||||
if (0) {
|
||||
ZEND_VM_C_LABEL(fcall_end):
|
||||
|
||||
zend_vm_stack_free_args(call);
|
||||
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
|
||||
zend_free_extra_named_params(call->extra_named_params);
|
||||
@ -6011,7 +6024,7 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO
|
||||
|
||||
bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
|
||||
if (UNEXPECTED(is_constant_deprecated)) {
|
||||
zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
|
||||
zend_deprecated_class_constant(c, constant_name);
|
||||
|
||||
if (EG(exception)) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
|
207
Zend/zend_vm_execute.h
generated
207
Zend/zend_vm_execute.h
generated
@ -1530,10 +1530,23 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
|
||||
zend_execute_data *call = EX(call);
|
||||
zend_function *fbc = call->func;
|
||||
zval *ret;
|
||||
zval retval;
|
||||
|
||||
SAVE_OPLINE();
|
||||
EX(call) = call->prev_execute_data;
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
UNDEF_RESULT();
|
||||
if (!0) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
goto fcall_by_name_end;
|
||||
}
|
||||
}
|
||||
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
|
||||
ret = NULL;
|
||||
if (0) {
|
||||
@ -1548,24 +1561,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
|
||||
|
||||
ZEND_VM_ENTER_EX();
|
||||
} else {
|
||||
zval retval;
|
||||
ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
|
||||
if (0) {
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
UNDEF_RESULT();
|
||||
if (!0) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
goto fcall_by_name_end;
|
||||
}
|
||||
}
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
@ -1593,7 +1593,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
|
||||
goto fcall_by_name_end;
|
||||
}
|
||||
|
||||
if (0) {
|
||||
fcall_by_name_end:
|
||||
|
||||
zend_vm_stack_free_args(call);
|
||||
|
||||
uint32_t call_info = ZEND_CALL_INFO(call);
|
||||
@ -1625,10 +1630,23 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
|
||||
zend_execute_data *call = EX(call);
|
||||
zend_function *fbc = call->func;
|
||||
zval *ret;
|
||||
zval retval;
|
||||
|
||||
SAVE_OPLINE();
|
||||
EX(call) = call->prev_execute_data;
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
UNDEF_RESULT();
|
||||
if (!1) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
goto fcall_by_name_end;
|
||||
}
|
||||
}
|
||||
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
|
||||
ret = NULL;
|
||||
if (1) {
|
||||
@ -1643,24 +1661,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
|
||||
|
||||
ZEND_VM_ENTER_EX();
|
||||
} else {
|
||||
zval retval;
|
||||
ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
|
||||
if (0) {
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
UNDEF_RESULT();
|
||||
if (!1) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
goto fcall_by_name_end;
|
||||
}
|
||||
}
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
@ -1688,7 +1693,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
|
||||
goto fcall_by_name_end;
|
||||
}
|
||||
|
||||
if (0) {
|
||||
fcall_by_name_end:
|
||||
|
||||
zend_vm_stack_free_args(call);
|
||||
|
||||
uint32_t call_info = ZEND_CALL_INFO(call);
|
||||
@ -1720,10 +1730,23 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_
|
||||
zend_execute_data *call = EX(call);
|
||||
zend_function *fbc = call->func;
|
||||
zval *ret;
|
||||
zval retval;
|
||||
|
||||
SAVE_OPLINE();
|
||||
EX(call) = call->prev_execute_data;
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
UNDEF_RESULT();
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
goto fcall_by_name_end;
|
||||
}
|
||||
}
|
||||
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
|
||||
ret = NULL;
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
@ -1739,24 +1762,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_
|
||||
|
||||
ZEND_VM_ENTER_EX();
|
||||
} else {
|
||||
zval retval;
|
||||
ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
|
||||
if (1) {
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
UNDEF_RESULT();
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
goto fcall_by_name_end;
|
||||
}
|
||||
}
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
@ -1786,7 +1796,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
|
||||
goto fcall_by_name_end;
|
||||
}
|
||||
|
||||
if (0) {
|
||||
fcall_by_name_end:
|
||||
|
||||
zend_vm_stack_free_args(call);
|
||||
|
||||
uint32_t call_info = ZEND_CALL_INFO(call);
|
||||
@ -1818,10 +1833,26 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
|
||||
zend_execute_data *call = EX(call);
|
||||
zend_function *fbc = call->func;
|
||||
zval *ret;
|
||||
zval retval;
|
||||
|
||||
SAVE_OPLINE();
|
||||
EX(call) = call->prev_execute_data;
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) {
|
||||
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func));
|
||||
}
|
||||
UNDEF_RESULT();
|
||||
if (!0) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
goto fcall_end;
|
||||
}
|
||||
}
|
||||
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
|
||||
ret = NULL;
|
||||
if (0) {
|
||||
@ -1846,24 +1877,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
|
||||
zend_execute_ex(call);
|
||||
}
|
||||
} else {
|
||||
zval retval;
|
||||
ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
|
||||
if (0) {
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
UNDEF_RESULT();
|
||||
if (!0) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
goto fcall_end;
|
||||
}
|
||||
}
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
@ -1896,7 +1914,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
|
||||
goto fcall_end;
|
||||
}
|
||||
|
||||
if (0) {
|
||||
fcall_end:
|
||||
|
||||
zend_vm_stack_free_args(call);
|
||||
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
|
||||
zend_free_extra_named_params(call->extra_named_params);
|
||||
@ -1927,10 +1950,26 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
|
||||
zend_execute_data *call = EX(call);
|
||||
zend_function *fbc = call->func;
|
||||
zval *ret;
|
||||
zval retval;
|
||||
|
||||
SAVE_OPLINE();
|
||||
EX(call) = call->prev_execute_data;
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) {
|
||||
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func));
|
||||
}
|
||||
UNDEF_RESULT();
|
||||
if (!1) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
goto fcall_end;
|
||||
}
|
||||
}
|
||||
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
|
||||
ret = NULL;
|
||||
if (1) {
|
||||
@ -1955,24 +1994,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
|
||||
zend_execute_ex(call);
|
||||
}
|
||||
} else {
|
||||
zval retval;
|
||||
ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
|
||||
if (0) {
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
UNDEF_RESULT();
|
||||
if (!1) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
goto fcall_end;
|
||||
}
|
||||
}
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
@ -2005,7 +2031,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
|
||||
goto fcall_end;
|
||||
}
|
||||
|
||||
if (0) {
|
||||
fcall_end:
|
||||
|
||||
zend_vm_stack_free_args(call);
|
||||
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
|
||||
zend_free_extra_named_params(call->extra_named_params);
|
||||
@ -2036,10 +2067,26 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_OBS
|
||||
zend_execute_data *call = EX(call);
|
||||
zend_function *fbc = call->func;
|
||||
zval *ret;
|
||||
zval retval;
|
||||
|
||||
SAVE_OPLINE();
|
||||
EX(call) = call->prev_execute_data;
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) {
|
||||
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func));
|
||||
}
|
||||
UNDEF_RESULT();
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
goto fcall_end;
|
||||
}
|
||||
}
|
||||
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
|
||||
ret = NULL;
|
||||
if (RETURN_VALUE_USED(opline)) {
|
||||
@ -2064,24 +2111,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_OBS
|
||||
zend_execute_ex(call);
|
||||
}
|
||||
} else {
|
||||
zval retval;
|
||||
ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
|
||||
if (1) {
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
|
||||
zend_deprecated_function(fbc);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
UNDEF_RESULT();
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
ret = &retval;
|
||||
ZVAL_UNDEF(ret);
|
||||
}
|
||||
goto fcall_end;
|
||||
}
|
||||
}
|
||||
|
||||
call->prev_execute_data = execute_data;
|
||||
EG(current_execute_data) = call;
|
||||
|
||||
@ -2116,7 +2150,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_OBS
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
|
||||
goto fcall_end;
|
||||
}
|
||||
|
||||
if (0) {
|
||||
fcall_end:
|
||||
|
||||
zend_vm_stack_free_args(call);
|
||||
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
|
||||
zend_free_extra_named_params(call->extra_named_params);
|
||||
@ -7526,7 +7565,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
|
||||
|
||||
bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
|
||||
if (UNEXPECTED(is_constant_deprecated)) {
|
||||
zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
|
||||
zend_deprecated_class_constant(c, constant_name);
|
||||
|
||||
if (EG(exception)) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
@ -8691,7 +8730,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
|
||||
|
||||
bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
|
||||
if (UNEXPECTED(is_constant_deprecated)) {
|
||||
zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
|
||||
zend_deprecated_class_constant(c, constant_name);
|
||||
|
||||
if (EG(exception)) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
@ -25407,7 +25446,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
|
||||
|
||||
bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
|
||||
if (UNEXPECTED(is_constant_deprecated)) {
|
||||
zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
|
||||
zend_deprecated_class_constant(c, constant_name);
|
||||
|
||||
if (EG(exception)) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
@ -25980,7 +26019,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
|
||||
|
||||
bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
|
||||
if (UNEXPECTED(is_constant_deprecated)) {
|
||||
zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
|
||||
zend_deprecated_class_constant(c, constant_name);
|
||||
|
||||
if (EG(exception)) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
@ -34575,7 +34614,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
|
||||
|
||||
bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
|
||||
if (UNEXPECTED(is_constant_deprecated)) {
|
||||
zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
|
||||
zend_deprecated_class_constant(c, constant_name);
|
||||
|
||||
if (EG(exception)) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
@ -34938,7 +34977,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
|
||||
|
||||
bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED;
|
||||
if (UNEXPECTED(is_constant_deprecated)) {
|
||||
zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name));
|
||||
zend_deprecated_class_constant(c, constant_name);
|
||||
|
||||
if (EG(exception)) {
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
|
@ -1583,6 +1583,13 @@ class FuncInfo {
|
||||
$flags[] = "ZEND_ACC_DEPRECATED";
|
||||
}
|
||||
|
||||
foreach ($this->attributes as $attr) {
|
||||
if ($attr->class === "Deprecated") {
|
||||
$flags[] = "ZEND_ACC_DEPRECATED";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$php82AndAboveFlags = $flags;
|
||||
if ($this->isMethod() === false && $this->supportsCompileTimeEval) {
|
||||
$php82AndAboveFlags[] = "ZEND_ACC_COMPILE_TIME_EVAL";
|
||||
@ -2865,6 +2872,13 @@ class ConstInfo extends VariableLike
|
||||
$flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_DEPRECATED", PHP_80_VERSION_ID);
|
||||
}
|
||||
|
||||
foreach ($this->attributes as $attr) {
|
||||
if ($attr->class === "Deprecated") {
|
||||
$flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_DEPRECATED", PHP_80_VERSION_ID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->flags & Modifiers::FINAL) {
|
||||
$flags = $this->addFlagForVersionsAbove($flags, "ZEND_ACC_FINAL", PHP_81_VERSION_ID);
|
||||
}
|
||||
@ -3103,11 +3117,18 @@ class AttributeInfo {
|
||||
/** @param array<string, ConstInfo> $allConstInfos */
|
||||
public function generateCode(string $invocation, string $nameSuffix, array $allConstInfos, ?int $phpVersionIdMinimumCompatibility): string {
|
||||
$php82MinimumCompatibility = $phpVersionIdMinimumCompatibility === null || $phpVersionIdMinimumCompatibility >= PHP_82_VERSION_ID;
|
||||
$php84MinimumCompatibility = $phpVersionIdMinimumCompatibility === null || $phpVersionIdMinimumCompatibility >= PHP_84_VERSION_ID;
|
||||
/* see ZEND_KNOWN_STRINGS in Zend/strings.h */
|
||||
$knowns = [];
|
||||
$knowns = [
|
||||
"message" => "ZEND_STR_MESSAGE",
|
||||
];
|
||||
if ($php82MinimumCompatibility) {
|
||||
$knowns["SensitiveParameter"] = "ZEND_STR_SENSITIVEPARAMETER";
|
||||
}
|
||||
if ($php84MinimumCompatibility) {
|
||||
$knowns["Deprecated"] = "ZEND_STR_DEPRECATED";
|
||||
$knowns["since"] = "ZEND_STR_SINCE";
|
||||
}
|
||||
|
||||
$code = "\n";
|
||||
$escapedAttributeName = strtr($this->class, '\\', '_');
|
||||
@ -3124,7 +3145,11 @@ class AttributeInfo {
|
||||
$code .= $value->initializeZval($zvalName);
|
||||
$code .= "\tZVAL_COPY_VALUE(&attribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].value, &$zvalName);\n";
|
||||
if ($arg->name) {
|
||||
$code .= "\tattribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].name = zend_string_init_interned(\"{$arg->name->name}\", sizeof(\"{$arg->name->name}\") - 1, 1);\n";
|
||||
if (isset($knowns[$arg->name->name])) {
|
||||
$code .= "\tattribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].name = ZSTR_KNOWN({$knowns[$arg->name->name]});\n";
|
||||
} else {
|
||||
$code .= "\tattribute_{$escapedAttributeName}_{$nameSuffix}->args[$i].name = zend_string_init_interned(\"{$arg->name->name}\", sizeof(\"{$arg->name->name}\") - 1, 1);\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
return $code;
|
||||
|
@ -9750,7 +9750,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen
|
||||
|
||||
jit_SET_EX_OPLINE(jit, opline);
|
||||
|
||||
if (opline->opcode == ZEND_DO_FCALL) {
|
||||
if (opline->opcode == ZEND_DO_FCALL || opline->opcode == ZEND_DO_FCALL_BY_NAME) {
|
||||
if (!func) {
|
||||
if (trace) {
|
||||
uint32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
|
||||
@ -9787,7 +9787,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen
|
||||
}
|
||||
}
|
||||
|
||||
if (opline->opcode == ZEND_DO_FCALL) {
|
||||
if (opline->opcode == ZEND_DO_FCALL || opline->opcode == ZEND_DO_FCALL_BY_NAME) {
|
||||
if (!func) {
|
||||
if (!trace) {
|
||||
ir_ref if_deprecated, ret;
|
||||
@ -10140,48 +10140,6 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen
|
||||
if (!func && (opline->opcode != ZEND_DO_ICALL)) {
|
||||
ir_IF_FALSE(if_user);
|
||||
}
|
||||
if (opline->opcode == ZEND_DO_FCALL_BY_NAME) {
|
||||
if (!func) {
|
||||
if (trace) {
|
||||
uint32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
|
||||
|
||||
exit_addr = zend_jit_trace_get_exit_addr(exit_point);
|
||||
if (!exit_addr) {
|
||||
return 0;
|
||||
}
|
||||
ZEND_ASSERT(func_ref);
|
||||
ir_GUARD_NOT(
|
||||
ir_AND_U32(
|
||||
ir_LOAD_U32(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, fn_flags))),
|
||||
ir_CONST_U32(ZEND_ACC_DEPRECATED)),
|
||||
ir_CONST_ADDR(exit_addr));
|
||||
} else {
|
||||
ir_ref if_deprecated, ret;
|
||||
|
||||
if_deprecated = ir_IF(ir_AND_U32(
|
||||
ir_LOAD_U32(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, fn_flags))),
|
||||
ir_CONST_U32(ZEND_ACC_DEPRECATED)));
|
||||
ir_IF_TRUE_cold(if_deprecated);
|
||||
|
||||
if (GCC_GLOBAL_REGS) {
|
||||
ret = ir_CALL(IR_BOOL, ir_CONST_FC_FUNC(zend_jit_deprecated_helper));
|
||||
} else {
|
||||
ret = ir_CALL_1(IR_BOOL, ir_CONST_FC_FUNC(zend_jit_deprecated_helper), rx);
|
||||
}
|
||||
ir_GUARD(ret, jit_STUB_ADDR(jit, jit_stub_exception_handler));
|
||||
ir_MERGE_WITH_EMPTY_FALSE(if_deprecated);
|
||||
}
|
||||
} else if (func->common.fn_flags & ZEND_ACC_DEPRECATED) {
|
||||
ir_ref ret;
|
||||
|
||||
if (GCC_GLOBAL_REGS) {
|
||||
ret = ir_CALL(IR_BOOL, ir_CONST_FC_FUNC(zend_jit_deprecated_helper));
|
||||
} else {
|
||||
ret = ir_CALL_1(IR_BOOL, ir_CONST_FC_FUNC(zend_jit_deprecated_helper), rx);
|
||||
}
|
||||
ir_GUARD(ret, jit_STUB_ADDR(jit, jit_stub_exception_handler));
|
||||
}
|
||||
}
|
||||
|
||||
// JIT: EG(current_execute_data) = execute_data;
|
||||
ir_STORE(jit_EG(current_execute_data), rx);
|
||||
|
@ -0,0 +1,59 @@
|
||||
--TEST--
|
||||
ReflectionAttribute::newInstance(): #[\Deprecated]
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
#[\Deprecated]
|
||||
function test1() {
|
||||
}
|
||||
|
||||
#[\Deprecated()]
|
||||
function test2() {
|
||||
}
|
||||
|
||||
#[\Deprecated("use test() instead")]
|
||||
function test3() {
|
||||
}
|
||||
|
||||
#[\Deprecated(since: "2.0")]
|
||||
function test4() {
|
||||
}
|
||||
|
||||
$reflection = new ReflectionFunction('test1');
|
||||
var_dump($reflection->getAttributes()[0]->newInstance());
|
||||
|
||||
$reflection = new ReflectionFunction('test2');
|
||||
var_dump($reflection->getAttributes()[0]->newInstance());
|
||||
|
||||
$reflection = new ReflectionFunction('test3');
|
||||
var_dump($reflection->getAttributes()[0]->newInstance());
|
||||
|
||||
$reflection = new ReflectionFunction('test4');
|
||||
var_dump($reflection->getAttributes()[0]->newInstance());
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
object(Deprecated)#%d (2) {
|
||||
["message"]=>
|
||||
NULL
|
||||
["since"]=>
|
||||
NULL
|
||||
}
|
||||
object(Deprecated)#%d (2) {
|
||||
["message"]=>
|
||||
NULL
|
||||
["since"]=>
|
||||
NULL
|
||||
}
|
||||
object(Deprecated)#%d (2) {
|
||||
["message"]=>
|
||||
string(18) "use test() instead"
|
||||
["since"]=>
|
||||
NULL
|
||||
}
|
||||
object(Deprecated)#%d (2) {
|
||||
["message"]=>
|
||||
NULL
|
||||
["since"]=>
|
||||
string(3) "2.0"
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
ReflectionClassConstant::isDeprecated() with userland constants.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Clazz {
|
||||
#[\Deprecated]
|
||||
public const TEST = 'test';
|
||||
}
|
||||
|
||||
|
||||
$r = new ReflectionClassConstant('Clazz', 'TEST');
|
||||
var_dump($r->isDeprecated());
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(true)
|
@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
ReflectionClassConstant::isDeprecated() with userland functions.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
#[\Deprecated]
|
||||
function test() {
|
||||
}
|
||||
|
||||
$r = new ReflectionFunction('test');
|
||||
|
||||
var_dump($r->isDeprecated());
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(true)
|
@ -0,0 +1,29 @@
|
||||
--TEST--
|
||||
ReflectionMethod::isDeprecated(): Implementing a deprecated interface method.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
interface I {
|
||||
#[\Deprecated]
|
||||
function test();
|
||||
}
|
||||
|
||||
class Clazz implements I {
|
||||
function test() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$c = new Clazz();
|
||||
$c->test();
|
||||
|
||||
$r = new ReflectionMethod('I', 'test');
|
||||
var_dump($r->isDeprecated());
|
||||
|
||||
$r = new ReflectionMethod('Clazz', 'test');
|
||||
var_dump($r->isDeprecated());
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
bool(false)
|
@ -0,0 +1,29 @@
|
||||
--TEST--
|
||||
ReflectionMethod::isDeprecated(): Implementing a deprecated abstract method.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
abstract class P {
|
||||
#[\Deprecated]
|
||||
abstract function test();
|
||||
}
|
||||
|
||||
class Clazz extends P {
|
||||
function test() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$c = new Clazz();
|
||||
$c->test();
|
||||
|
||||
$r = new ReflectionMethod('P', 'test');
|
||||
var_dump($r->isDeprecated());
|
||||
|
||||
$r = new ReflectionMethod('Clazz', 'test');
|
||||
var_dump($r->isDeprecated());
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
bool(false)
|
@ -124,6 +124,11 @@ static ZEND_FUNCTION(zend_test_deprecated)
|
||||
zend_parse_parameters(ZEND_NUM_ARGS(), "|z", &arg1);
|
||||
}
|
||||
|
||||
static ZEND_FUNCTION(zend_test_deprecated_attr)
|
||||
{
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
}
|
||||
|
||||
/* Create a string without terminating null byte. Must be terminated with
|
||||
* zend_terminate_string() before destruction, otherwise a warning is issued
|
||||
* in debug builds. */
|
||||
|
@ -43,6 +43,9 @@ namespace {
|
||||
*/
|
||||
public const int ZEND_TEST_DEPRECATED = 42;
|
||||
|
||||
#[\Deprecated(message: "custom message")]
|
||||
public const int ZEND_TEST_DEPRECATED_ATTR = 42;
|
||||
|
||||
/** @var mixed */
|
||||
public static $_StaticProp;
|
||||
public static int $staticIntProp = 123;
|
||||
@ -206,6 +209,9 @@ namespace {
|
||||
/** @deprecated */
|
||||
function zend_test_deprecated(mixed $arg = null): void {}
|
||||
|
||||
#[\Deprecated(message: "custom message")]
|
||||
function zend_test_deprecated_attr(): void {}
|
||||
|
||||
/** @alias zend_test_void_return */
|
||||
function zend_test_aliased(): void {}
|
||||
|
||||
|
39
ext/zend_test/test_arginfo.h
generated
39
ext/zend_test/test_arginfo.h
generated
@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 6b49c60e3b86415a0e0d95cd915419fac39de531 */
|
||||
* Stub hash: 470b6d507911cf05279de3557df03831858dd8c1 */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
@ -20,6 +20,8 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_deprecated, 0, 0, IS_V
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, arg, IS_MIXED, 0, "null")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_zend_test_deprecated_attr arginfo_zend_test_void_return
|
||||
|
||||
#define arginfo_zend_test_aliased arginfo_zend_test_void_return
|
||||
|
||||
#define arginfo_zend_test_deprecated_aliased arginfo_zend_test_void_return
|
||||
@ -253,6 +255,7 @@ static ZEND_FUNCTION(zend_test_nullable_array_return);
|
||||
static ZEND_FUNCTION(zend_test_void_return);
|
||||
static ZEND_FUNCTION(zend_test_compile_string);
|
||||
static ZEND_FUNCTION(zend_test_deprecated);
|
||||
static ZEND_FUNCTION(zend_test_deprecated_attr);
|
||||
static ZEND_FUNCTION(zend_create_unterminated_string);
|
||||
static ZEND_FUNCTION(zend_terminate_string);
|
||||
static ZEND_FUNCTION(zend_leak_variable);
|
||||
@ -343,6 +346,11 @@ static const zend_function_entry ext_functions[] = {
|
||||
#else
|
||||
ZEND_RAW_FENTRY("zend_test_deprecated", zif_zend_test_deprecated, arginfo_zend_test_deprecated, ZEND_ACC_DEPRECATED)
|
||||
#endif
|
||||
#if (PHP_VERSION_ID >= 80400)
|
||||
ZEND_RAW_FENTRY("zend_test_deprecated_attr", zif_zend_test_deprecated_attr, arginfo_zend_test_deprecated_attr, ZEND_ACC_DEPRECATED, NULL, NULL)
|
||||
#else
|
||||
ZEND_RAW_FENTRY("zend_test_deprecated_attr", zif_zend_test_deprecated_attr, arginfo_zend_test_deprecated_attr, ZEND_ACC_DEPRECATED)
|
||||
#endif
|
||||
#if (PHP_VERSION_ID >= 80400)
|
||||
ZEND_RAW_FENTRY("zend_test_aliased", zif_zend_test_void_return, arginfo_zend_test_aliased, 0, NULL, NULL)
|
||||
#else
|
||||
@ -563,6 +571,15 @@ static void register_test_symbols(int module_number)
|
||||
REGISTER_STRING_CONSTANT("ZendTestNS2\\ZendSubNS\\ZEND_CONSTANT_A", "namespaced", CONST_PERSISTENT);
|
||||
|
||||
|
||||
zend_string *attribute_name_Deprecated_func_zend_test_deprecated_attr_0 = zend_string_init_interned("Deprecated", sizeof("Deprecated") - 1, 1);
|
||||
zend_attribute *attribute_Deprecated_func_zend_test_deprecated_attr_0 = zend_add_function_attribute(zend_hash_str_find_ptr(CG(function_table), "zend_test_deprecated_attr", sizeof("zend_test_deprecated_attr") - 1), attribute_name_Deprecated_func_zend_test_deprecated_attr_0, 1);
|
||||
zend_string_release(attribute_name_Deprecated_func_zend_test_deprecated_attr_0);
|
||||
zval attribute_Deprecated_func_zend_test_deprecated_attr_0_arg0;
|
||||
zend_string *attribute_Deprecated_func_zend_test_deprecated_attr_0_arg0_str = zend_string_init("custom message", strlen("custom message"), 1);
|
||||
ZVAL_STR(&attribute_Deprecated_func_zend_test_deprecated_attr_0_arg0, attribute_Deprecated_func_zend_test_deprecated_attr_0_arg0_str);
|
||||
ZVAL_COPY_VALUE(&attribute_Deprecated_func_zend_test_deprecated_attr_0->args[0].value, &attribute_Deprecated_func_zend_test_deprecated_attr_0_arg0);
|
||||
attribute_Deprecated_func_zend_test_deprecated_attr_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE);
|
||||
|
||||
zend_string *attribute_name_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0 = zend_string_init_interned("ZendTestParameterAttribute", sizeof("ZendTestParameterAttribute") - 1, 1);
|
||||
zend_attribute *attribute_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0 = zend_add_parameter_attribute(zend_hash_str_find_ptr(CG(function_table), "zend_test_parameter_with_attribute", sizeof("zend_test_parameter_with_attribute") - 1), 0, attribute_name_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0, 1);
|
||||
zend_string_release(attribute_name_ZendTestParameterAttribute_func_zend_test_parameter_with_attribute_arg0_0);
|
||||
@ -647,6 +664,16 @@ static zend_class_entry *register_class__ZendTestClass(zend_class_entry *class_e
|
||||
#endif
|
||||
zend_string_release(const_ZEND_TEST_DEPRECATED_name);
|
||||
|
||||
zval const_ZEND_TEST_DEPRECATED_ATTR_value;
|
||||
ZVAL_LONG(&const_ZEND_TEST_DEPRECATED_ATTR_value, 42);
|
||||
zend_string *const_ZEND_TEST_DEPRECATED_ATTR_name = zend_string_init_interned("ZEND_TEST_DEPRECATED_ATTR", sizeof("ZEND_TEST_DEPRECATED_ATTR") - 1, 1);
|
||||
#if (PHP_VERSION_ID >= 80300)
|
||||
zend_class_constant *const_ZEND_TEST_DEPRECATED_ATTR = zend_declare_typed_class_constant(class_entry, const_ZEND_TEST_DEPRECATED_ATTR_name, &const_ZEND_TEST_DEPRECATED_ATTR_value, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
|
||||
#else
|
||||
zend_class_constant *const_ZEND_TEST_DEPRECATED_ATTR = zend_declare_class_constant_ex(class_entry, const_ZEND_TEST_DEPRECATED_ATTR_name, &const_ZEND_TEST_DEPRECATED_ATTR_value, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL);
|
||||
#endif
|
||||
zend_string_release(const_ZEND_TEST_DEPRECATED_ATTR_name);
|
||||
|
||||
zval property__StaticProp_default_value;
|
||||
ZVAL_NULL(&property__StaticProp_default_value);
|
||||
zend_string *property__StaticProp_name = zend_string_init("_StaticProp", sizeof("_StaticProp") - 1, 1);
|
||||
@ -708,6 +735,16 @@ static zend_class_entry *register_class__ZendTestClass(zend_class_entry *class_e
|
||||
#endif
|
||||
zend_string_release(property_readonlyProp_name);
|
||||
|
||||
|
||||
zend_string *attribute_name_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0 = zend_string_init_interned("Deprecated", sizeof("Deprecated") - 1, 1);
|
||||
zend_attribute *attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0 = zend_add_class_constant_attribute(class_entry, const_ZEND_TEST_DEPRECATED_ATTR, attribute_name_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0, 1);
|
||||
zend_string_release(attribute_name_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0);
|
||||
zval attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0_arg0;
|
||||
zend_string *attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0_arg0_str = zend_string_init("custom message", strlen("custom message"), 1);
|
||||
ZVAL_STR(&attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0_arg0, attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0_arg0_str);
|
||||
ZVAL_COPY_VALUE(&attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0->args[0].value, &attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0_arg0);
|
||||
attribute_Deprecated_const_ZEND_TEST_DEPRECATED_ATTR_0->args[0].name = ZSTR_KNOWN(ZEND_STR_MESSAGE);
|
||||
|
||||
return class_entry;
|
||||
}
|
||||
|
||||
|
40
ext/zend_test/tests/attribute-deprecated.phpt
Normal file
40
ext/zend_test/tests/attribute-deprecated.phpt
Normal file
@ -0,0 +1,40 @@
|
||||
--TEST--
|
||||
#[\Deprecated]: Works in stubs.
|
||||
--EXTENSIONS--
|
||||
zend_test
|
||||
--FILE--
|
||||
<?php
|
||||
zend_test_deprecated();
|
||||
zend_test_deprecated_attr();
|
||||
|
||||
$reflection = new ReflectionFunction('zend_test_deprecated_attr');
|
||||
var_dump($reflection->getAttributes()[0]->newInstance());
|
||||
var_dump($reflection->isDeprecated());
|
||||
|
||||
_ZendTestClass::ZEND_TEST_DEPRECATED_ATTR;
|
||||
|
||||
$reflection = new ReflectionClassConstant('_ZendTestClass', 'ZEND_TEST_DEPRECATED_ATTR');
|
||||
var_dump($reflection->getAttributes()[0]->newInstance());
|
||||
var_dump($reflection->isDeprecated());
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Function zend_test_deprecated() is deprecated in %s on line %d
|
||||
|
||||
Deprecated: Function zend_test_deprecated_attr() is deprecated, custom message in %s on line %d
|
||||
object(Deprecated)#%d (2) {
|
||||
["message"]=>
|
||||
string(14) "custom message"
|
||||
["since"]=>
|
||||
NULL
|
||||
}
|
||||
bool(true)
|
||||
|
||||
Deprecated: Constant _ZendTestClass::ZEND_TEST_DEPRECATED_ATTR is deprecated, custom message in %s on line %d
|
||||
object(Deprecated)#%d (2) {
|
||||
["message"]=>
|
||||
string(14) "custom message"
|
||||
["since"]=>
|
||||
NULL
|
||||
}
|
||||
bool(true)
|
Loading…
Reference in New Issue
Block a user