Skip to content

Commit f61f122

Browse files
committed
Merge branch 'PHP-7.4'
2 parents b59f6e4 + 4b9ebd8 commit f61f122

20 files changed

+253
-51
lines changed

Zend/tests/bug30519.phpt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@ class test implements a {
66
}
77
?>
88
--EXPECTF--
9-
Fatal error: Interface 'a' not found in %sbug30519.php on line 2
9+
Fatal error: Uncaught Error: Interface 'a' not found in %s:%d
10+
Stack trace:
11+
#0 {main}
12+
thrown in %s on line %d

Zend/tests/bug30922.phpt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@ var_dump($a instanceOf A);
1010
echo "ok\n";
1111
?>
1212
--EXPECTF--
13-
Fatal error: Interface 'RecurisiveFooFar' not found in %s on line %d
13+
Fatal error: Uncaught Error: Interface 'RecurisiveFooFar' not found in %s:%d
14+
Stack trace:
15+
#0 {main}
16+
thrown in %s on line %d

Zend/tests/bug49908.phpt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,14 @@ var_dump(new Foo());
2424
--EXPECTF--
2525
string(3) "Foo"
2626
string(3) "Bar"
27+
string(3) "Foo"
28+
string(3) "Bar"
2729

28-
Fatal error: During class fetch: Uncaught Exception: Bar in %s:%d
30+
Fatal error: Uncaught Exception: Bar in %s:%d
2931
Stack trace:
3032
#0 [internal function]: {closure}('Bar')
3133
#1 %s(%d): spl_autoload_call('Bar')
3234
#2 [internal function]: {closure}('Foo')
3335
#3 %s(%d): spl_autoload_call('Foo')
34-
#4 {main} in %s on line %d
36+
#4 {main}
37+
thrown in %s on line %d
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
--TEST--
2+
Exception while loading class -- parent case
3+
--FILE--
4+
<?php
5+
6+
spl_autoload_register(function($class) {
7+
throw new Exception("Class $class does not exist");
8+
});
9+
10+
// Graceful failure allowed
11+
for ($i = 0; $i < 2; $i++) {
12+
try {
13+
class B extends A {
14+
}
15+
} catch (Exception $e) {
16+
echo $e->getMessage(), "\n";
17+
}
18+
}
19+
20+
interface I {}
21+
22+
spl_autoload_register(function($class) {
23+
// Tie up B in a variance obligation.
24+
class X {
25+
public function test(): I {}
26+
}
27+
class Y extends X {
28+
public function test(): B {}
29+
}
30+
}, true, true);
31+
32+
// Fallback to fatal error, as we can't unlink class B anymore.
33+
try {
34+
class B extends A implements I {
35+
}
36+
} catch (Exception $e) {
37+
echo $e->getMessage(), "\n";
38+
}
39+
40+
?>
41+
--EXPECTF--
42+
Class A does not exist
43+
Class A does not exist
44+
45+
Fatal error: During inheritance of B with variance dependencies: Uncaught Exception: Class A does not exist in %s:%d
46+
Stack trace:
47+
#0 [internal function]: {closure}('A')
48+
#1 %s(%d): spl_autoload_call('A')
49+
#2 {main} in %s on line %d
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
--TEST--
2+
Exception while loading class -- interface case
3+
--FILE--
4+
<?php
5+
6+
spl_autoload_register(function($class) {
7+
throw new Exception("Class $class does not exist");
8+
});
9+
10+
class A {}
11+
12+
// Graceful failure allowed
13+
for ($i = 0; $i < 2; $i++) {
14+
try {
15+
class B extends A implements I {
16+
}
17+
} catch (Exception $e) {
18+
echo $e->getMessage(), "\n";
19+
}
20+
}
21+
22+
interface J {}
23+
24+
spl_autoload_register(function($class) {
25+
// Tie up B in a variance obligation.
26+
class X {
27+
public function test(): J {}
28+
}
29+
class Y extends X {
30+
public function test(): B {}
31+
}
32+
}, true, true);
33+
34+
// Fallback to fatal error, as we can't unlink class B anymore.
35+
try {
36+
class B extends A implements I, J {
37+
}
38+
} catch (Exception $e) {
39+
echo $e->getMessage(), "\n";
40+
}
41+
42+
?>
43+
--EXPECTF--
44+
Class I does not exist
45+
Class I does not exist
46+
47+
Fatal error: During inheritance of B with variance dependencies: Uncaught Exception: Class I does not exist in %s:%d
48+
Stack trace:
49+
#0 [internal function]: {closure}('I')
50+
#1 %s(%d): spl_autoload_call('I')
51+
#2 {main} in %s on line %d

Zend/tests/type_declarations/variance/unlinked_parent_1.phpt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ spl_autoload_register(function($class) {
77
class X extends B {}
88
});
99

10-
class B extends A {
10+
try {
11+
class B extends A {
12+
}
13+
} catch (Error $e) {
14+
echo $e->getMessage(), "\n";
1115
}
1216

1317
?>
14-
--EXPECTF--
15-
Fatal error: Class 'B' not found in %s on line %d
18+
--EXPECT--
19+
Class 'B' not found

Zend/tests/type_declarations/variance/unlinked_parent_2.phpt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ spl_autoload_register(function($class) {
77
class X implements B {}
88
});
99

10-
interface B extends A {
10+
try {
11+
interface B extends A {
12+
}
13+
} catch (Error $e) {
14+
echo $e->getMessage(), "\n";
1115
}
1216

1317
?>
14-
--EXPECTF--
15-
Fatal error: Interface 'B' not found in %s on line %d
18+
--EXPECT--
19+
Interface 'B' not found

Zend/tests/use_unlinked_class.phpt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ class A implements I {
1212

1313
?>
1414
--EXPECTF--
15-
Fatal error: During class fetch: Uncaught ReflectionException: Class A does not exist in %s:%d
15+
Fatal error: Uncaught ReflectionException: Class A does not exist in %s:%d
1616
Stack trace:
1717
#0 %s(%d): ReflectionClass->__construct('A')
1818
#1 [internal function]: {closure}('I')
1919
#2 %s(%d): spl_autoload_call('I')
20-
#3 {main} in %s on line %d
20+
#3 {main}
21+
thrown in %s on line %d

Zend/zend_compile.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1071,7 +1071,11 @@ ZEND_API int do_bind_class(zval *lcname, zend_string *lc_parent_name) /* {{{ */
10711071
return FAILURE;
10721072
}
10731073

1074-
zend_do_link_class(ce, lc_parent_name);
1074+
if (zend_do_link_class(ce, lc_parent_name) == FAILURE) {
1075+
zend_hash_set_bucket_key(EG(class_table), (Bucket *) zv, Z_STR_P(rtd_key));
1076+
return FAILURE;
1077+
}
1078+
10751079
return SUCCESS;
10761080
}
10771081
/* }}} */

Zend/zend_compile.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ typedef struct _zend_oparray_context {
229229
/* op_array or class is preloaded | | | */
230230
#define ZEND_ACC_PRELOADED (1 << 10) /* X | X | | */
231231
/* | | | */
232-
/* Class Flags (unused: 23...) | | | */
232+
/* Class Flags (unused: 24...) | | | */
233233
/* =========== | | | */
234234
/* | | | */
235235
/* Special class types | | | */
@@ -281,6 +281,9 @@ typedef struct _zend_oparray_context {
281281
/* Class is linked apart from variance obligations. | | | */
282282
#define ZEND_ACC_NEARLY_LINKED (1 << 22) /* X | | | */
283283
/* | | | */
284+
/* Whether this class was used in its unlinked state. | | | */
285+
#define ZEND_ACC_HAS_UNLINKED_USES (1 << 23) /* X | | | */
286+
/* | | | */
284287
/* Function Flags (unused: 17, 23, 26) | | | */
285288
/* ============== | | | */
286289
/* | | | */

0 commit comments

Comments
 (0)