Skip to content

Commit 0502cfe

Browse files
committed
More explicit error for use after evaluation error
1 parent 230784c commit 0502cfe

File tree

8 files changed

+69
-11
lines changed

8 files changed

+69
-11
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
Error during evaluation of static/constants
3+
--FILE--
4+
<?php
5+
6+
try {
7+
class A {
8+
public const C = 42;
9+
public static $s1 = UNKNOWN;
10+
public static $s2 = 42;
11+
}
12+
} catch (Error $e) {
13+
echo $e->getMessage(), "\n";
14+
}
15+
try {
16+
var_dump(A::$s2);
17+
} catch (Error $e) {
18+
echo $e->getMessage(), "\n";
19+
}
20+
try {
21+
var_dump(new A);
22+
} catch (Error $e) {
23+
echo $e->getMessage(), "\n";
24+
}
25+
try {
26+
var_dump(new A);
27+
} catch (Error $e) {
28+
echo $e->getMessage(), "\n";
29+
}
30+
try {
31+
// TODO: Should this fail?
32+
var_dump(A::C);
33+
} catch (Error $e) {
34+
echo $e->getMessage(), "\n";
35+
}
36+
37+
?>
38+
--EXPECT--
39+
Undefined constant "UNKNOWN"
40+
Trying to use class for which initializer evaluation has previously failed
41+
Trying to use class for which initializer evaluation has previously failed
42+
Trying to use class for which initializer evaluation has previously failed
43+
int(42)

Zend/tests/type_declarations/typed_properties_058.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,5 @@ for ($i = 0; $i < 2; $i++) {
3333
--EXPECT--
3434
Cannot assign int to property B::$foo of type string
3535
int(5)
36-
Cannot assign int to property B::$foo of type string
37-
Cannot assign int to property B::$foo of type string
36+
Trying to use class for which initializer evaluation has previously failed
37+
Trying to use class for which initializer evaluation has previously failed

Zend/zend_API.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,9 +1349,14 @@ ZEND_API zend_result zend_update_class_constants(zend_class_entry *class_type) /
13491349
}
13501350
}
13511351

1352+
if (ce_flags & ZEND_ACC_CONSTANTS_UPDATE_FAILED) {
1353+
zend_throw_error(NULL, "Trying to use class for which initializer evaluation has previously failed");
1354+
return FAILURE;
1355+
}
1356+
13521357
if (class_type->parent) {
13531358
if (UNEXPECTED(zend_update_class_constants(class_type->parent) != SUCCESS)) {
1354-
return FAILURE;
1359+
goto failure;
13551360
}
13561361
}
13571362

@@ -1370,7 +1375,7 @@ ZEND_API zend_result zend_update_class_constants(zend_class_entry *class_type) /
13701375
if (Z_TYPE(c->value) == IS_CONSTANT_AST) {
13711376
val = &c->value;
13721377
if (UNEXPECTED(zval_update_constant_ex(val, c->ce) != SUCCESS)) {
1373-
return FAILURE;
1378+
goto failure;
13741379
}
13751380
}
13761381
} ZEND_HASH_FOREACH_END();
@@ -1424,17 +1429,17 @@ ZEND_API zend_result zend_update_class_constants(zend_class_entry *class_type) /
14241429
ZVAL_COPY(&tmp, val);
14251430
if (UNEXPECTED(zval_update_constant_ex(&tmp, prop_info->ce) != SUCCESS)) {
14261431
zval_ptr_dtor(&tmp);
1427-
return FAILURE;
1432+
goto failure;
14281433
}
14291434
/* property initializers must always be evaluated with strict types */;
14301435
if (UNEXPECTED(!zend_verify_property_type(prop_info, &tmp, /* strict */ 1))) {
14311436
zval_ptr_dtor(&tmp);
1432-
return FAILURE;
1437+
goto failure;
14331438
}
14341439
zval_ptr_dtor(val);
14351440
ZVAL_COPY_VALUE(val, &tmp);
14361441
} else if (UNEXPECTED(zval_update_constant_ex(val, prop_info->ce) != SUCCESS)) {
1437-
return FAILURE;
1442+
goto failure;
14381443
}
14391444
}
14401445
} ZEND_HASH_FOREACH_END();
@@ -1456,6 +1461,14 @@ ZEND_API zend_result zend_update_class_constants(zend_class_entry *class_type) /
14561461
}
14571462

14581463
return SUCCESS;
1464+
1465+
failure:
1466+
if (mutable_data) {
1467+
mutable_data->ce_flags |= ZEND_ACC_CONSTANTS_UPDATE_FAILED;
1468+
} else {
1469+
class_type->ce_flags |= ZEND_ACC_CONSTANTS_UPDATE_FAILED;
1470+
}
1471+
return FAILURE;
14591472
}
14601473
/* }}} */
14611474

Zend/zend_compile.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ typedef struct _zend_oparray_context {
299299
#define ZEND_ACC_HAS_AST_STATICS (1 << 26) /* X | | | */
300300
#define ZEND_ACC_HAS_DYNAMIC_AST_PROPERTIES (1 << 29)
301301
/* X | | | */
302+
/* An error was thrown during constant updating | | | */
303+
#define ZEND_ACC_CONSTANTS_UPDATE_FAILED (1 << 30) /* X | | | */
302304
/* | | | */
303305
/* loaded from file cache to process memory | | | */
304306
#define ZEND_ACC_FILE_CACHED (1 << 27) /* X | | | */

ext/standard/tests/filters/object_init_failure.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ Undefined constant "FOO"
2222
Warning: file_get_contents(): Unable to create or locate filter "sample.filter" in %s on line %d
2323

2424
Warning: file_get_contents(): Unable to create filter (sample.filter) in %s on line %d
25-
Undefined constant "FOO"
25+
Trying to use class for which initializer evaluation has previously failed

ext/standard/tests/filters/object_init_failure_2.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ Undefined constant "FOO"
2222
Warning: main(): Unable to create or locate filter "sample.filter" in %s on line %d
2323

2424
Warning: main(): Unable to create filter (sample.filter) in %s on line %d
25-
Undefined constant "FOO"
25+
Trying to use class for which initializer evaluation has previously failed

ext/standard/tests/streams/bug77664.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ file_get_contents('error://test');
1616
--EXPECTF--
1717
Undefined constant self::INVALID
1818

19-
Fatal error: Uncaught Error: Undefined constant self::INVALID in %s:%d
19+
Fatal error: Uncaught Error: Trying to use class for which initializer evaluation has previously failed in %s:%d
2020
Stack trace:
2121
#0 %sbug77664.php(%d): file_get_contents('error://test')
2222
#1 {main}

ext/tokenizer/tests/PhpToken_extension_errors.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,5 @@ try {
3131
?>
3232
--EXPECT--
3333
Undefined constant "UNKNOWN"
34-
Undefined constant "UNKNOWN"
34+
Trying to use class for which initializer evaluation has previously failed
3535
Cannot instantiate abstract class MyPhpToken2

0 commit comments

Comments
 (0)