summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_API.c4
-rw-r--r--Zend/zend_API.h2
-rw-r--r--Zend/zend_compile.h3
-rw-r--r--Zend/zend_execute_API.c12
-rw-r--r--Zend/zend_vm_def.h14
-rw-r--r--Zend/zend_vm_execute.h14
-rw-r--r--ext/reflection/php_reflection.c16
-rw-r--r--main/php.h2
8 files changed, 59 insertions, 8 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 00f5166f04..d1766d4610 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -1554,7 +1554,9 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, zend_function_entr
}
if (ptr->flags) {
if (!(ptr->flags & ZEND_ACC_PPP_MASK)) {
- zend_error(error_type, "Invalid access level for %s%s%s() - access must be exactly one of public, protected or private", scope ? scope->name : "", scope ? "::" : "", ptr->fname);
+ if (ptr->flags != ZEND_ACC_DEPRECATED || scope) {
+ zend_error(error_type, "Invalid access level for %s%s%s() - access must be exactly one of public, protected or private", scope ? scope->name : "", scope ? "::" : "", ptr->fname);
+ }
internal_function->fn_flags = ZEND_ACC_PUBLIC | ptr->flags;
} else {
internal_function->fn_flags = ptr->flags;
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index 054494501a..837335fd22 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -50,7 +50,9 @@ typedef struct _zend_function_entry {
#define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0)
#define ZEND_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, 0)
+#define ZEND_DEP_FE(name, arg_info) ZEND_FENTRY(name, ZEND_FN(name), arg_info, ZEND_ACC_DEPRECATED)
#define ZEND_FALIAS(name, alias, arg_info) ZEND_FENTRY(name, ZEND_FN(alias), arg_info, 0)
+#define ZEND_DEP_FALIAS(name, alias, arg_info) ZEND_FENTRY(name, ZEND_FN(alias), arg_info, ZEND_ACC_DEPRECATED)
#define ZEND_ME(classname, name, arg_info, flags) ZEND_FENTRY(name, ZEND_FN(classname##_##name), arg_info, flags)
#define ZEND_ABSTRACT_ME(classname, name, arg_info) ZEND_FENTRY(name, NULL, arg_info, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT)
#define ZEND_MALIAS(classname, name, alias, arg_info, flags) \
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 6ac818cff4..9c94f59109 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -136,6 +136,9 @@ typedef struct _zend_try_catch_element {
/* shadow of parent's private method/property */
#define ZEND_ACC_SHADOW 0x20000
+/* deprecation flag */
+#define ZEND_ACC_DEPRECATED 0x40000
+
char *zend_visibility_string(zend_uint fn_flags);
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 1950890b7a..40a7d9ba5b 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -803,6 +803,18 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
calling_scope = fci_cache->calling_scope;
fci->object_pp = fci_cache->object_pp;
}
+
+ if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) {
+ if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) {
+ zend_error_noreturn(E_ERROR, "Cannot call abstract method %v::%v()", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name);
+ }
+ if (EX(function_state).function->common.fn_flags & ZEND_ACC_DEPRECATED) {
+ zend_error(E_STRICT, "Function %s%s%s() is deprecated",
+ EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : "",
+ EX(function_state).function->common.scope ? "::" : "",
+ EX(function_state).function->common.function_name);
+ }
+ }
for (i=0; i<fci->param_count; i++) {
zval *param;
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 97d705bc12..f0ecd2b460 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -1784,9 +1784,17 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
zend_bool should_change_scope;
zend_op *ctor_opline;
- if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) {
- zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name);
- ZEND_VM_NEXT_OPCODE(); /* Never reached */
+ if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) {
+ if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) {
+ zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name);
+ ZEND_VM_NEXT_OPCODE(); /* Never reached */
+ }
+ if (EX(function_state).function->common.fn_flags & ZEND_ACC_DEPRECATED) {
+ zend_error(E_STRICT, "Function %s%s%s() is deprecated",
+ EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : "",
+ EX(function_state).function->common.scope ? "::" : "",
+ EX(function_state).function->common.function_name);
+ };
}
zend_ptr_stack_2_push(&EG(argument_stack), (void *) opline->extended_value, NULL);
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 1a2f2c76c9..0cb9fb16a0 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -132,9 +132,17 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
zend_bool should_change_scope;
zend_op *ctor_opline;
- if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) {
- zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name);
- ZEND_VM_NEXT_OPCODE(); /* Never reached */
+ if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) {
+ if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) {
+ zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name);
+ ZEND_VM_NEXT_OPCODE(); /* Never reached */
+ }
+ if (EX(function_state).function->common.fn_flags & ZEND_ACC_DEPRECATED) {
+ zend_error(E_STRICT, "Function %s%s%s() is deprecated",
+ EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : "",
+ EX(function_state).function->common.scope ? "::" : "",
+ EX(function_state).function->common.function_name);
+ };
}
zend_ptr_stack_2_push(&EG(argument_stack), (void *) opline->extended_value, NULL);
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index fc0d1e710c..9fcd270bf7 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -671,6 +671,9 @@ static void _function_string(string *str, zend_function *fptr, zend_class_entry
string_printf(str, fptr->common.scope ? "%sMethod [ " : "%sFunction [ ", indent);
string_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : "<internal");
+ if (fptr->common.fn_flags & ZEND_ACC_DEPRECATED) {
+ string_printf(str, ", deprecated");
+ }
#if MBO_0
if (fptr->type == ZEND_INTERNAL_FUNCTION && ((zend_internal_function*)fptr)->module) {
string_printf(str, ":%s", ((zend_internal_function*)fptr)->module->name);
@@ -2366,6 +2369,14 @@ ZEND_METHOD(reflection_method, isStatic)
}
/* }}} */
+/* {{{ proto public bool ReflectionFunction::isDeprecated()
+ Returns whether this function is deprecated */
+ZEND_METHOD(reflection_function, isDeprecated)
+{
+ _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_DEPRECATED);
+}
+/* }}} */
+
/* {{{ proto public bool ReflectionMethod::isConstructor()
Returns whether this method is the constructor */
ZEND_METHOD(reflection_method, isConstructor)
@@ -4097,6 +4108,7 @@ static zend_function_entry reflection_function_functions[] = {
ZEND_ME(reflection_function, getExtension, NULL, 0)
ZEND_ME(reflection_function, getExtensionName, NULL, 0)
#endif
+ ZEND_ME(reflection_function, isDeprecated, NULL, 0)
{NULL, NULL, NULL}
};
@@ -4197,7 +4209,7 @@ static zend_function_entry reflection_parameter_functions[] = {
ZEND_ME(reflection_parameter, getName, NULL, 0)
ZEND_ME(reflection_parameter, isPassedByReference, NULL, 0)
ZEND_ME(reflection_parameter, getDeclaringClass, NULL, 0)
- ZEND_MALIAS(reflection_parameter, getClass, getDeclaringClass, NULL, 0)
+ ZEND_MALIAS(reflection_parameter, getClass, getDeclaringClass, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED)
ZEND_ME(reflection_parameter, isArray, NULL, 0)
ZEND_ME(reflection_parameter, allowsNull, NULL, 0)
ZEND_ME(reflection_parameter, isOptional, NULL, 0)
@@ -4271,6 +4283,8 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */
reflection_register_implement(reflection_function_ptr, reflector_ptr TSRMLS_CC);
zend_declare_property_string(reflection_function_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
+ REGISTER_REFLECTION_CLASS_CONST_LONG(function, "IS_DEPRECATED", ZEND_ACC_DEPRECATED);
+
INIT_CLASS_ENTRY(_reflection_entry, "ReflectionParameter", reflection_parameter_functions);
_reflection_entry.create_object = reflection_objects_new;
reflection_parameter_ptr = zend_register_internal_class(&_reflection_entry TSRMLS_CC);
diff --git a/main/php.h b/main/php.h
index a667152e76..0dbb55c570 100644
--- a/main/php.h
+++ b/main/php.h
@@ -340,7 +340,9 @@ END_EXTERN_C()
#define PHP_NAMED_FE ZEND_NAMED_FE
#define PHP_FE ZEND_FE
+#define PHP_DEP_FE ZEND_DEP_FE
#define PHP_FALIAS ZEND_FALIAS
+#define PHP_DEP_FALIAS ZEND_DEP_FALIAS
#define PHP_ME ZEND_ME
#define PHP_MALIAS ZEND_MALIAS
#define PHP_ABSTRACT_ME ZEND_ABSTRACT_ME