summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2007-11-09 13:34:39 +0000
committerDmitry Stogov <dmitry@php.net>2007-11-09 13:34:39 +0000
commit8646d9afce989718cde927c526684bbbc1c96e97 (patch)
tree6df3ed493b06a1dfa41b96751bb5a3640fb67455
parent98b3c247a88e9a2f14b25e859c4048a9e16a2a08 (diff)
downloadphp-git-8646d9afce989718cde927c526684bbbc1c96e97.tar.gz
Fixed type-hint compatibility check in namespaces
-rwxr-xr-xZend/tests/ns_056.phpt31
-rw-r--r--Zend/zend_compile.c13
2 files changed, 43 insertions, 1 deletions
diff --git a/Zend/tests/ns_056.phpt b/Zend/tests/ns_056.phpt
new file mode 100755
index 0000000000..0bc4f0087d
--- /dev/null
+++ b/Zend/tests/ns_056.phpt
@@ -0,0 +1,31 @@
+--TEST--
+056: type-hint compatibility in namespaces
+--SKIPIF--
+<?php if (!extension_loaded("spl")) die("skip SPL is no available"); ?>
+--FILE--
+<?php
+namespace test::ns1;
+
+class Foo implements SplObserver {
+ function update(SplSubject $x) {
+ echo "ok\n";
+ }
+}
+
+class Bar implements SplSubject {
+ function attach(SplObserver $x) {
+ echo "ok\n";
+ }
+ function notify() {
+ }
+ function detach(SplObserver $x) {
+ }
+}
+$foo = new Foo();
+$bar = new Bar();
+$bar->attach($foo);
+$foo->update($bar);
+?>
+--EXPECT--
+ok
+ok
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 4d70797daa..30dabbe4c5 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2176,7 +2176,18 @@ static zend_bool zend_do_perform_implementation_check(zend_function *fe, zend_fu
}
if (fe->common.arg_info[i].class_name
&& strcmp(fe->common.arg_info[i].class_name, proto->common.arg_info[i].class_name)!=0) {
- return 0;
+ char *colon;
+
+ if (fe->common.type == ZEND_USER_FUNCTION &&
+ strchr(proto->common.arg_info[i].class_name, ':') == NULL &&
+ (colon = zend_memrchr(fe->common.arg_info[i].class_name, ':', fe->common.arg_info[i].class_name_len)) != NULL &&
+ strcmp(colon+1, proto->common.arg_info[i].class_name) == 0) {
+ efree((char*)fe->common.arg_info[i].class_name);
+ fe->common.arg_info[i].class_name = estrndup(proto->common.arg_info[i].class_name, proto->common.arg_info[i].class_name_len);
+ fe->common.arg_info[i].class_name_len = proto->common.arg_info[i].class_name_len;
+ } else {
+ return 0;
+ }
}
if (fe->common.arg_info[i].array_type_hint != proto->common.arg_info[i].array_type_hint) {
/* Only one has an array type hint and the other one doesn't */