From: Guilherme Blanco Date: Thu, 12 Feb 2015 22:19:14 +0000 (+0100) Subject: Made ZEND_ACC_TRAIT a saner value X-Git-Tag: PRE_PHP7_EREG_MYSQL_REMOVALS~172 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8c81d80e10e0f189307fc8ff4a8fb34bd0cb1fcb;p=php Made ZEND_ACC_TRAIT a saner value CC_TRAIT valued as 0x120 is too magical to be comprehensible by others. --- diff --git a/Zend/zend_API.c b/Zend/zend_API.c index bd0f330a2f..fe6ae33802 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1090,11 +1090,14 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties) * calling zend_merge_properties(). */ ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties ZEND_FILE_LINE_DC) /* {{{ */ { - if (class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { - char *what = (class_type->ce_flags & ZEND_ACC_INTERFACE) ? "interface" - :((class_type->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) ? "trait" - : "abstract class"; - zend_error(E_ERROR, "Cannot instantiate %s %s", what, class_type->name->val); + if (class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { + if (class_type->ce_flags & ZEND_ACC_INTERFACE) { + zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", class_type->name->val); + } else if (class_type->ce_flags & ZEND_ACC_TRAIT) { + zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", class_type->name->val); + } else { + zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", class_type->name->val); + } } zend_update_class_constants(class_type); diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index fe7c8f7556..dca0890b14 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1378,14 +1378,16 @@ ZEND_FUNCTION(class_exists) } else { lc_name = zend_string_tolower(class_name); } + ce = zend_hash_find_ptr(EG(class_table), lc_name); zend_string_release(lc_name); RETURN_BOOL(ce && !((ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT)) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)); } ce = zend_lookup_class(class_name); + if (ce) { - RETURN_BOOL((ce->ce_flags & (ZEND_ACC_INTERFACE | (ZEND_ACC_TRAIT - ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) == 0); + RETURN_BOOL((ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT)) == 0); } else { RETURN_FALSE; } @@ -1462,6 +1464,7 @@ ZEND_FUNCTION(trait_exists) } else { lc_name = zend_string_tolower(trait_name); } + ce = zend_hash_find_ptr(EG(class_table), lc_name); zend_string_release(lc_name); RETURN_BOOL(ce && ((ce->ce_flags & ZEND_ACC_TRAIT) > ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)); @@ -1806,7 +1809,7 @@ ZEND_FUNCTION(get_declared_traits) Returns an array of all declared classes. */ ZEND_FUNCTION(get_declared_classes) { - uint32_t mask = ZEND_ACC_INTERFACE | (ZEND_ACC_TRAIT & ~ZEND_ACC_EXPLICIT_ABSTRACT_CLASS); + uint32_t mask = ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT; uint32_t comply = 0; if (zend_parse_parameters_none() == FAILURE) { diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 1fcc7e1b31..90c7ec34b3 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -984,7 +984,7 @@ ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array if (parent_ce->ce_flags & ZEND_ACC_INTERFACE) { zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from interface %s", ce->name->val, parent_ce->name->val); - } else if ((parent_ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { + } else if (parent_ce->ce_flags & ZEND_ACC_TRAIT) { zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from trait %s", ce->name->val, parent_ce->name->val); } @@ -4022,7 +4022,7 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo { zend_class_entry *ce = CG(active_class_entry); zend_bool in_interface = (ce->ce_flags & ZEND_ACC_INTERFACE) != 0; - zend_bool in_trait = ZEND_CE_IS_TRAIT(ce); + zend_bool in_trait = (ce->ce_flags & ZEND_ACC_TRAIT) != 0; zend_bool is_public = (op_array->fn_flags & ZEND_ACC_PUBLIC) != 0; zend_bool is_static = (op_array->fn_flags & ZEND_ACC_STATIC) != 0; @@ -4384,7 +4384,7 @@ void zend_compile_class_const_decl(zend_ast *ast) /* {{{ */ zend_string *name = zend_ast_get_str(name_ast); zval value_zv; - if (ZEND_CE_IS_TRAIT(ce)) { + if ((ce->ce_flags & ZEND_ACC_TRAIT) != 0) { zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants"); return; } @@ -5088,7 +5088,7 @@ static zend_bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */ break; case T_CLASS_C: if (ce) { - if (ZEND_CE_IS_TRAIT(ce)) { + if ((ce->ce_flags & ZEND_ACC_TRAIT) != 0) { return 0; } else { ZVAL_STR_COPY(zv, ce->name); @@ -5098,7 +5098,7 @@ static zend_bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */ } break; case T_TRAIT_C: - if (ce && ZEND_CE_IS_TRAIT(ce)) { + if (ce && (ce->ce_flags & ZEND_ACC_TRAIT) != 0) { ZVAL_STR_COPY(zv, ce->name); } else { ZVAL_EMPTY_STRING(zv); @@ -5987,7 +5987,7 @@ void zend_compile_magic_const(znode *result, zend_ast *ast) /* {{{ */ ZEND_ASSERT(ast->attr == T_CLASS_C && CG(active_class_entry) && - ZEND_CE_IS_TRAIT(CG(active_class_entry))); + (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != 0); { zend_ast *const_ast = zend_ast_create(ZEND_AST_CONST, @@ -6122,7 +6122,7 @@ void zend_compile_const_expr_magic_const(zend_ast **ast_ptr) /* {{{ */ /* Other cases already resolved by constant folding */ ZEND_ASSERT(ast->attr == T_CLASS_C && CG(active_class_entry) && - ZEND_CE_IS_TRAIT(CG(active_class_entry))); + (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != 0); { zval const_zv; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index d39f1285f4..1104a29b82 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -191,8 +191,8 @@ typedef struct _zend_try_catch_element { /* ZEND_ACC_EXPLICIT_ABSTRACT_CLASS denotes that a class was explicitly defined as abstract by using the keyword. */ #define ZEND_ACC_IMPLICIT_ABSTRACT_CLASS 0x10 #define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS 0x20 -#define ZEND_ACC_INTERFACE 0x80 -#define ZEND_ACC_TRAIT 0x120 +#define ZEND_ACC_INTERFACE 0x40 +#define ZEND_ACC_TRAIT 0x80 /* method flags (visibility) */ /* The order of those must be kept - public < protected < private */ @@ -258,8 +258,6 @@ typedef struct _zend_try_catch_element { /* Function has a return type hint (or class has such non-private function) */ #define ZEND_ACC_HAS_RETURN_TYPE 0x40000000 -#define ZEND_CE_IS_TRAIT(ce) (((ce)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) - char *zend_visibility_string(uint32_t fn_flags); typedef struct _zend_property_info { diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index c6a0d8f0c9..0554e31a5e 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1395,7 +1395,7 @@ void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */ zend_function *func; zend_abstract_info ai; - if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { + if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & (ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) { memset(&ai, 0, sizeof(ai)); ZEND_HASH_FOREACH_PTR(&ce->function_table, func) { diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index bcbf3c7b75..dbd81d8e1d 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -1126,7 +1126,7 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s zend_get_function_declaration(existing_fn)->val); } return; - } else if ((existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { + } else if (existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT) { /* two traits can't define the same non-abstract method */ #if 1 zend_error_noreturn(E_COMPILE_ERROR, "Trait method %s has not been applied, because there are collisions with other trait methods on %s", diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 479f7b7151..858a3f777e 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3893,10 +3893,10 @@ ZEND_VM_HANDLER(68, ZEND_NEW, CONST|VAR, ANY) } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (UNEXPECTED((ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) { + if (UNEXPECTED((ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) { if (ce->ce_flags & ZEND_ACC_INTERFACE) { zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", ce->name->val); - } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { + } else if (ce->ce_flags & ZEND_ACC_TRAIT) { zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", ce->name->val); } else { zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", ce->name->val); @@ -5880,7 +5880,7 @@ ZEND_VM_HANDLER(154, ZEND_ADD_TRAIT, ANY, ANY) CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } - if (!((trait->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT)) { + if (!(trait->ce_flags & ZEND_ACC_TRAIT)) { zend_error_noreturn(E_ERROR, "%s cannot use %s - it is not a trait", ce->name->val, trait->name->val); } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), trait); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 4ef0779089..6d24cac6d4 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1189,7 +1189,7 @@ static int ZEND_FASTCALL ZEND_ADD_TRAIT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } - if (!((trait->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT)) { + if (!(trait->ce_flags & ZEND_ACC_TRAIT)) { zend_error_noreturn(E_ERROR, "%s cannot use %s - it is not a trait", ce->name->val, trait->name->val); } CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), trait); @@ -2727,7 +2727,7 @@ static int ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (UNEXPECTED((ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) { if (ce->ce_flags & ZEND_ACC_INTERFACE) { zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", ce->name->val); - } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { + } else if (ce->ce_flags & ZEND_ACC_TRAIT) { zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", ce->name->val); } else { zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", ce->name->val); @@ -11806,10 +11806,10 @@ static int ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (UNEXPECTED((ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) { + if (UNEXPECTED((ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) { if (ce->ce_flags & ZEND_ACC_INTERFACE) { zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", ce->name->val); - } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { + } else if (ce->ce_flags & ZEND_ACC_TRAIT) { zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", ce->name->val); } else { zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", ce->name->val); diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 92b5d9da5f..309b10c1bb 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -374,7 +374,7 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in char *kind = "Class"; if (ce->ce_flags & ZEND_ACC_INTERFACE) { kind = "Interface"; - } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { + } else if (ce->ce_flags & ZEND_ACC_TRAIT) { kind = "Trait"; } string_printf(str, "%s%s [ ", indent, kind); @@ -389,7 +389,7 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in } if (ce->ce_flags & ZEND_ACC_INTERFACE) { string_printf(str, "interface "); - } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { + } else if (ce->ce_flags & ZEND_ACC_TRAIT) { string_printf(str, "trait "); } else { if (ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { @@ -4143,7 +4143,7 @@ ZEND_METHOD(reflection_class, isInterface) Returns whether this is a trait */ ZEND_METHOD(reflection_class, isTrait) { - _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_TRAIT & ~ZEND_ACC_EXPLICIT_ABSTRACT_CLASS); + _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_TRAIT); } /* }}} */ diff --git a/ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt b/ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt index 8d2bd47d12..68189db2bb 100644 --- a/ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt +++ b/ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt @@ -31,7 +31,7 @@ dump_modifiers('g'); int(0) int(32) int(4) -int(128) +int(64) int(524288) -int(524416) +int(524352) int(0) diff --git a/ext/reflection/tests/ReflectionClass_modifiers_001.phpt b/ext/reflection/tests/ReflectionClass_modifiers_001.phpt index 1e0a97dfe0..7f62b565a2 100644 --- a/ext/reflection/tests/ReflectionClass_modifiers_001.phpt +++ b/ext/reflection/tests/ReflectionClass_modifiers_001.phpt @@ -41,4 +41,4 @@ int(4) bool(false) bool(true) bool(false) -int(128) \ No newline at end of file +int(64) \ No newline at end of file