Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2d6b28a

Browse files
Use attribute validator for assigning flags
1 parent ba97d86 commit 2d6b28a

File tree

4 files changed

+80
-93
lines changed

4 files changed

+80
-93
lines changed

‎Zend/zend_attributes.c‎

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ uint32_t zend_attribute_attribute_get_flags(zend_attribute *attr, zend_class_ent
7070
}
7171

7272
static void validate_allow_dynamic_properties(
73-
zend_attribute *attr, uint32_t target, zend_class_entry *scope)
73+
zend_attribute *attr, uint32_t target_type, zend_class_entry *scope, void*target, uint32_toffset)
7474
{
7575
if (scope->ce_flags & ZEND_ACC_TRAIT) {
7676
zend_error_noreturn(E_ERROR, "Cannot apply #[\\AllowDynamicProperties] to trait %s",
@@ -96,7 +96,7 @@ static void validate_allow_dynamic_properties(
9696
}
9797

9898
static void validate_attribute(
99-
zend_attribute *attr, uint32_t target, zend_class_entry *scope)
99+
zend_attribute *attr, uint32_t target_type, zend_class_entry *scope, void*target, uint32_toffset)
100100
{
101101
const char *msg = NULL;
102102
if (scope->ce_flags & ZEND_ACC_TRAIT) {
@@ -113,6 +113,51 @@ static void validate_attribute(
113113
}
114114
}
115115

116+
static void validate_override(
117+
zend_attribute *attr, uint32_t target_type, zend_class_entry *scope, void *target, uint32_t offset)
118+
{
119+
if (target_type & ZEND_ATTRIBUTE_TARGET_METHOD) {
120+
zend_op_array *op_array = target;
121+
op_array->fn_flags |= ZEND_ACC_OVERRIDE;
122+
} else {
123+
ZEND_ASSERT(target_type & ZEND_ATTRIBUTE_TARGET_PROPERTY);
124+
zend_property_info *prop_info = target;
125+
prop_info->flags |= ZEND_ACC_OVERRIDE;
126+
}
127+
}
128+
129+
static void validate_deprecated(
130+
zend_attribute *attr, uint32_t target_type, zend_class_entry *scope, void *target, uint32_t offset)
131+
{
132+
if (target_type & (ZEND_ATTRIBUTE_TARGET_FUNCTION|ZEND_ATTRIBUTE_TARGET_METHOD)) {
133+
zend_op_array *op_array = target;
134+
op_array->fn_flags |= ZEND_ACC_DEPRECATED;
135+
} else if (target_type & (ZEND_ATTRIBUTE_TARGET_CLASS_CONST)) {
136+
zend_class_constant *c = target;
137+
ZEND_CLASS_CONST_FLAGS(c) |= ZEND_ACC_DEPRECATED;
138+
/* For deprecated constants, we need to flag the zval for recursion
139+
* detection. Make sure the zval is separated out of shm. */
140+
scope->ce_flags |= ZEND_ACC_HAS_AST_CONSTANTS;
141+
scope->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
142+
} else {
143+
ZEND_ASSERT(target_type & ZEND_ATTRIBUTE_TARGET_CONST);
144+
zend_constant *c = target;
145+
ZEND_CONSTANT_SET_FLAGS(
146+
c,
147+
ZEND_CONSTANT_FLAGS(c) | CONST_DEPRECATED,
148+
ZEND_CONSTANT_MODULE_NUMBER(c)
149+
);
150+
}
151+
}
152+
153+
static void validate_no_discard(
154+
zend_attribute *attr, uint32_t target_type, zend_class_entry *scope, void *target, uint32_t offset)
155+
{
156+
ZEND_ASSERT(target_type & (ZEND_ATTRIBUTE_TARGET_FUNCTION|ZEND_ATTRIBUTE_TARGET_METHOD));
157+
zend_op_array *op_array = target;
158+
op_array->fn_flags |= ZEND_ACC_NODISCARD;
159+
}
160+
116161
ZEND_METHOD(Attribute, __construct)
117162
{
118163
zend_long flags = ZEND_ATTRIBUTE_TARGET_ALL;
@@ -560,13 +605,16 @@ void zend_register_attribute_ce(void)
560605
zend_ce_sensitive_parameter_value->default_object_handlers = &attributes_object_handlers_sensitive_parameter_value;
561606

562607
zend_ce_override = register_class_Override();
563-
zend_mark_internal_attribute(zend_ce_override);
608+
attr = zend_mark_internal_attribute(zend_ce_override);
609+
attr->validator = validate_override;
564610

565611
zend_ce_deprecated = register_class_Deprecated();
566612
attr = zend_mark_internal_attribute(zend_ce_deprecated);
613+
attr->validator = validate_deprecated;
567614

568615
zend_ce_nodiscard = register_class_NoDiscard();
569616
attr = zend_mark_internal_attribute(zend_ce_nodiscard);
617+
attr->validator = validate_no_discard;
570618
}
571619

572620
void zend_attributes_shutdown(void)

‎Zend/zend_attributes.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ typedef struct _zend_attribute {
7070
typedef struct _zend_internal_attribute {
7171
zend_class_entry *ce;
7272
uint32_t flags;
73-
void (*validator)(zend_attribute *attr, uint32_t target, zend_class_entry *scope);
73+
/* Parameter offsets start at 1, everything else uses 0. */
74+
void (*validator)(zend_attribute *attr, uint32_t target_type, zend_class_entry *scope, void *target, uint32_t offset);
7475
} zend_internal_attribute;
7576

7677
ZEND_API zend_attribute *zend_get_attribute(HashTable *attributes, zend_string *lcname);

‎Zend/zend_compile.c‎

Lines changed: 21 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -7468,7 +7468,7 @@ static bool zend_is_valid_default_value(zend_type type, zval *value)
74687468
}
74697469

74707470
static void zend_compile_attributes(
7471-
HashTable **attributes, zend_ast *ast, uint32_t offset, uint32_t target, uint32_t promoted
7471+
HashTable **attributes, zend_ast *ast, uint32_t offset, uint32_t target_type, uint32_t promoted, void*target
74727472
) /* {{{ */ {
74737473
zend_attribute *attr;
74747474
zend_internal_attribute *config;
@@ -7502,7 +7502,7 @@ static void zend_compile_attributes(
75027502
zend_string_release(lcname);
75037503

75047504
/* Exclude internal attributes that do not match on promoted properties. */
7505-
if (config && !(target & (config->flags & ZEND_ATTRIBUTE_TARGET_ALL))) {
7505+
if (config && !(target_type & (config->flags & ZEND_ATTRIBUTE_TARGET_ALL))) {
75067506
if (promoted & (config->flags & ZEND_ATTRIBUTE_TARGET_ALL)) {
75077507
zend_string_release(name);
75087508
continue;
@@ -7560,8 +7560,8 @@ static void zend_compile_attributes(
75607560
continue;
75617561
}
75627562

7563-
if (!(target & (config->flags & ZEND_ATTRIBUTE_TARGET_ALL))) {
7564-
zend_string *location = zend_get_attribute_target_names(target);
7563+
if (!(target_type & (config->flags & ZEND_ATTRIBUTE_TARGET_ALL))) {
7564+
zend_string *location = zend_get_attribute_target_names(target_type);
75657565
zend_string *allowed = zend_get_attribute_target_names(config->flags);
75667566

75677567
zend_error_noreturn(E_ERROR, "Attribute \"%s\" cannot target %s (allowed targets: %s)",
@@ -7575,8 +7575,9 @@ static void zend_compile_attributes(
75757575
}
75767576
}
75777577

7578-
if (config->validator != NULL) {
7579-
config->validator(attr, target, CG(active_class_entry));
7578+
/* target is NULL for global constants at compile-time. Validator will be called at runtime. */
7579+
if (config->validator != NULL && target) {
7580+
config->validator(attr, target_type, CG(active_class_entry), target, offset);
75807581
}
75817582
} ZEND_HASH_FOREACH_END();
75827583
}
@@ -7773,13 +7774,6 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32
77737774
arg_info->name = zend_string_copy(name);
77747775
arg_info->type = (zend_type) ZEND_TYPE_INIT_NONE(0);
77757776

7776-
if (attributes_ast) {
7777-
zend_compile_attributes(
7778-
&op_array->attributes, attributes_ast, i + 1, ZEND_ATTRIBUTE_TARGET_PARAMETER,
7779-
is_promoted ? ZEND_ATTRIBUTE_TARGET_PROPERTY : 0
7780-
);
7781-
}
7782-
77837777
bool forced_allow_nullable = false;
77847778
if (type_ast) {
77857779
uint32_t default_type = *default_ast_ptr ? Z_TYPE(default_node.u.constant) : IS_UNDEF;
@@ -7835,6 +7829,13 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32
78357829
zval_ptr_dtor(&default_node.u.constant);
78367830
}
78377831

7832+
if (attributes_ast) {
7833+
zend_compile_attributes(
7834+
&op_array->attributes, attributes_ast, i + 1, ZEND_ATTRIBUTE_TARGET_PARAMETER,
7835+
is_promoted ? ZEND_ATTRIBUTE_TARGET_PROPERTY : 0, op_array
7836+
);
7837+
}
7838+
78387839
opline = zend_emit_op(NULL, opcode, NULL, &default_node);
78397840
SET_NODE(opline->result, &var_node);
78407841
opline->op1.num = i + 1;
@@ -7917,12 +7918,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32
79177918
}
79187919
if (attributes_ast) {
79197920
zend_compile_attributes(
7920-
&prop->attributes, attributes_ast, 0, ZEND_ATTRIBUTE_TARGET_PROPERTY, ZEND_ATTRIBUTE_TARGET_PARAMETER);
7921-
7922-
zend_attribute *override_attribute = zend_get_attribute_str(prop->attributes, "override", sizeof("override")-1);
7923-
if (override_attribute) {
7924-
prop->flags |= ZEND_ACC_OVERRIDE;
7925-
}
7921+
&prop->attributes, attributes_ast, 0, ZEND_ATTRIBUTE_TARGET_PROPERTY, ZEND_ATTRIBUTE_TARGET_PARAMETER, prop);
79267922
}
79277923
}
79287924
}
@@ -8429,37 +8425,7 @@ static zend_op_array *zend_compile_func_decl_ex(
84298425
target = ZEND_ATTRIBUTE_TARGET_METHOD;
84308426
}
84318427

8432-
zend_compile_attributes(&op_array->attributes, decl->child[4], 0, target, 0);
8433-
8434-
zend_attribute *override_attribute = zend_get_attribute_str(
8435-
op_array->attributes,
8436-
"override",
8437-
sizeof("override")-1
8438-
);
8439-
8440-
if (override_attribute) {
8441-
op_array->fn_flags |= ZEND_ACC_OVERRIDE;
8442-
}
8443-
8444-
zend_attribute *deprecated_attribute = zend_get_attribute_str(
8445-
op_array->attributes,
8446-
"deprecated",
8447-
sizeof("deprecated")-1
8448-
);
8449-
8450-
if (deprecated_attribute) {
8451-
op_array->fn_flags |= ZEND_ACC_DEPRECATED;
8452-
}
8453-
8454-
zend_attribute *nodiscard_attribute = zend_get_attribute_str(
8455-
op_array->attributes,
8456-
"nodiscard",
8457-
sizeof("nodiscard")-1
8458-
);
8459-
8460-
if (nodiscard_attribute) {
8461-
op_array->fn_flags |= ZEND_ACC_NODISCARD;
8462-
}
8428+
zend_compile_attributes(&op_array->attributes, decl->child[4], 0, target, 0, op_array);
84638429
}
84648430

84658431
/* Do not leak the class scope into free standing functions, even if they are dynamically
@@ -8901,12 +8867,7 @@ static void zend_compile_prop_decl(zend_ast *ast, zend_ast *type_ast, uint32_t f
89018867
}
89028868

89038869
if (attr_ast) {
8904-
zend_compile_attributes(&info->attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_PROPERTY, 0);
8905-
8906-
zend_attribute *override_attribute = zend_get_attribute_str(info->attributes, "override", sizeof("override")-1);
8907-
if (override_attribute) {
8908-
info->flags |= ZEND_ACC_OVERRIDE;
8909-
}
8870+
zend_compile_attributes(&info->attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_PROPERTY, 0, info);
89108871
}
89118872

89128873
CG(context).active_property_info_name = old_active_property_info_name;
@@ -8983,17 +8944,7 @@ static void zend_compile_class_const_decl(zend_ast *ast, uint32_t flags, zend_as
89838944
c = zend_declare_typed_class_constant(ce, name, &value_zv, flags, doc_comment, type);
89848945

89858946
if (attr_ast) {
8986-
zend_compile_attributes(&c->attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_CLASS_CONST, 0);
8987-
8988-
zend_attribute *deprecated = zend_get_attribute_str(c->attributes, "deprecated", sizeof("deprecated")-1);
8989-
8990-
if (deprecated) {
8991-
ZEND_CLASS_CONST_FLAGS(c) |= ZEND_ACC_DEPRECATED;
8992-
/* For deprecated constants, we need to flag the zval for recursion
8993-
* detection. Make sure the zval is separated out of shm. */
8994-
ce->ce_flags |= ZEND_ACC_HAS_AST_CONSTANTS;
8995-
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
8996-
}
8947+
zend_compile_attributes(&c->attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_CLASS_CONST, 0, c);
89978948
}
89988949
}
89998950
}
@@ -9263,7 +9214,7 @@ static void zend_compile_class_decl(znode *result, zend_ast *ast, bool toplevel)
92639214
CG(active_class_entry) = ce;
92649215

92659216
if (decl->child[3]) {
9266-
zend_compile_attributes(&ce->attributes, decl->child[3], 0, ZEND_ATTRIBUTE_TARGET_CLASS, 0);
9217+
zend_compile_attributes(&ce->attributes, decl->child[3], 0, ZEND_ATTRIBUTE_TARGET_CLASS, 0, ce);
92679218
}
92689219

92699220
if (implements_ast) {
@@ -9440,13 +9391,7 @@ static void zend_compile_enum_case(zend_ast *ast)
94409391

94419392
zend_ast *attr_ast = ast->child[3];
94429393
if (attr_ast) {
9443-
zend_compile_attributes(&c->attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_CLASS_CONST, 0);
9444-
9445-
zend_attribute *deprecated = zend_get_attribute_str(c->attributes, "deprecated", sizeof("deprecated")-1);
9446-
9447-
if (deprecated) {
9448-
ZEND_CLASS_CONST_FLAGS(c) |= ZEND_ACC_DEPRECATED;
9449-
}
9394+
zend_compile_attributes(&c->attributes, attr_ast, 0, ZEND_ATTRIBUTE_TARGET_CLASS_CONST, 0, c);
94509395
}
94519396
}
94529397

@@ -9660,7 +9605,7 @@ static void zend_compile_const_decl(zend_ast *ast) /* {{{ */
96609605
}
96619606

96629607
HashTable *attributes = NULL;
9663-
zend_compile_attributes(&attributes, list->child[1], 0, ZEND_ATTRIBUTE_TARGET_CONST, 0);
9608+
zend_compile_attributes(&attributes, list->child[1], 0, ZEND_ATTRIBUTE_TARGET_CONST, 0, NULL);
96649609

96659610
ZEND_ASSERT(last_op != NULL);
96669611
last_op->opcode = ZEND_DECLARE_ATTRIBUTED_CONST;

‎Zend/zend_constants.c‎

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -561,17 +561,10 @@ void zend_constant_add_attributes(zend_constant *c, HashTable *attributes) {
561561
GC_TRY_ADDREF(attributes);
562562
c->attributes = attributes;
563563

564-
zend_attribute *deprecated_attribute = zend_get_attribute_str(
565-
c->attributes,
566-
"deprecated",
567-
strlen("deprecated")
568-
);
569-
570-
if (deprecated_attribute) {
571-
ZEND_CONSTANT_SET_FLAGS(
572-
c,
573-
ZEND_CONSTANT_FLAGS(c) | CONST_DEPRECATED,
574-
ZEND_CONSTANT_MODULE_NUMBER(c)
575-
);
576-
}
564+
ZEND_HASH_PACKED_FOREACH_PTR(attributes, zend_attribute *attr) {
565+
zend_internal_attribute *config = zend_internal_attribute_get(attr->lcname);
566+
if (config && config->validator != NULL) {
567+
config->validator(attr, ZEND_ATTRIBUTE_TARGET_CONST, CG(active_class_entry), c, 0);
568+
}
569+
} ZEND_HASH_FOREACH_END();
577570
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /