summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_API.c13
-rw-r--r--Zend/zend_builtin_functions.c7
-rw-r--r--Zend/zend_compile.c14
-rw-r--r--Zend/zend_compile.h6
-rw-r--r--Zend/zend_execute_API.c2
-rw-r--r--Zend/zend_inheritance.c2
-rw-r--r--Zend/zend_vm_def.h6
-rw-r--r--Zend/zend_vm_execute.h8
-rw-r--r--ext/reflection/php_reflection.c6
-rw-r--r--ext/reflection/tests/ReflectionClass_getModifiers_basic.phpt4
-rw-r--r--ext/reflection/tests/ReflectionClass_modifiers_001.phpt2
11 files changed, 37 insertions, 33 deletions
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