]> granicus.if.org Git - php/commitdiff
Remove static calls from incompatible $this context
authorNikita Popov <nikic@php.net>
Wed, 10 Sep 2014 14:08:20 +0000 (16:08 +0200)
committerNikita Popov <nikic@php.net>
Sat, 17 Jan 2015 17:26:44 +0000 (18:26 +0100)
NEWS
UPGRADING
Zend/tests/incompat_ctx_user.phpt
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index 721a1ccf2069e92e8a9fd7ea51a14c5b5cc2fa09..6c9985d646d71121165a9ce0d2de49b5940f89bd 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -34,6 +34,8 @@
   . Fixed oversight where define() did not support arrays yet const syntax did. (Andrea, Dmitry)
   . Use "integer" and "float" instead of "long" and "double" in ZPP, type hint and conversion error messages. (Andrea)
   . Implemented FR #55428 (E_RECOVERABLE_ERROR when output buffering in output buffering handler). (Kalle)
+  . Removed scoped calls of non-static methods from an incompatible $this
+    context. (Nikita)
 
 - Date:
   . Fixed day_of_week function as it could sometimes return negative values
index 8506ba7ca5882befb9a9c2974b10d212ca353c0c..71197f9e3dbfbf93c4f650fce3d13ee57db35223 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -54,6 +54,8 @@ PHP X.Y UPGRADE NOTES
   . zend_function.common.num_args don't include the variadic argument anymore.
   . ob_start() no longer issues an E_ERROR, but instead an E_RECOVERABLE_ERROR in case an 
     output buffer is created in an output buffer handler.
+  . Remove support for scoped calls to non-static methods from an incompatible
+    $this context. See details in https://wiki.php.net/rfc/incompat_ctx.
   . Added zend_memnstr_ex, which is based on string matching sunday algo.
   . Added zend_memnrstr, zend_memnrstr_ex.
   . Added hybrid sorting algo zend_sort for better performance.
index 2d9b59c1e803093b839640c21a23ebce6a70f829..5923d5a7023b0a1501870b1c3fa0ea3092f147d6 100644 (file)
@@ -16,5 +16,4 @@ $b->bar();
 
 ?>
 --EXPECTF--
-Deprecated: Non-static method A::foo() should not be called statically, assuming $this from incompatible context in %s on line %d
-string(1) "B"
+Fatal error: Non-static method A::foo() cannot be called statically, assuming $this from incompatible context in %s on line %d
index dc3547a5e231c2835b2da234cb45e6f52a8f850d..0958002f439f50a31fa125beb70271d50618989e 100644 (file)
@@ -2471,24 +2471,24 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE
                        object = Z_OBJ(EX(This));
                        GC_REFCOUNT(object)++;
                }
-               if (!object ||
-                   !instanceof_function(object->ce, ce)) {
-                   /* We are calling method of the other (incompatible) class,
-                      but passing $this. This is done for compatibility with php-4. */
+               if (!object) {
                        if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
-                               zend_error(
-                                       object ? E_DEPRECATED : E_STRICT,
-                                       "Non-static method %s::%s() should not be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* We allow calling userland non-static methods without $this */
+                               zend_error(E_STRICT,
+                                       "Non-static method %s::%s() should not be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        } else {
-                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
-                               zend_error_noreturn(
-                                       E_ERROR,
-                                       "Non-static method %s::%s() cannot be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* An internal function assumes $this is present and won't check that.
+                                * So PHP would crash by allowing the call. */
+                               zend_error_noreturn(E_ERROR,
+                                       "Non-static method %s::%s() cannot be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        }
+               } else if (!instanceof_function(object->ce, ce)) {
+                       zend_error_noreturn(E_ERROR,
+                               "Non-static method %s::%s() cannot be called statically, "
+                               "assuming $this from incompatible context",
+                               fbc->common.scope->name->val, fbc->common.function_name->val);
                }
        }
 
index 1d56205e0839f41a460a2514c9e304791a014f8d..da9636eaaa90c846310d486bfe1dc992e8a33a52 100644 (file)
@@ -4257,24 +4257,24 @@ static int ZEND_FASTCALL  ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(
                        object = Z_OBJ(EX(This));
                        GC_REFCOUNT(object)++;
                }
-               if (!object ||
-                   !instanceof_function(object->ce, ce)) {
-                   /* We are calling method of the other (incompatible) class,
-                      but passing $this. This is done for compatibility with php-4. */
+               if (!object) {
                        if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
-                               zend_error(
-                                       object ? E_DEPRECATED : E_STRICT,
-                                       "Non-static method %s::%s() should not be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* We allow calling userland non-static methods without $this */
+                               zend_error(E_STRICT,
+                                       "Non-static method %s::%s() should not be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        } else {
-                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
-                               zend_error_noreturn(
-                                       E_ERROR,
-                                       "Non-static method %s::%s() cannot be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* An internal function assumes $this is present and won't check that.
+                                * So PHP would crash by allowing the call. */
+                               zend_error_noreturn(E_ERROR,
+                                       "Non-static method %s::%s() cannot be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        }
+               } else if (!instanceof_function(object->ce, ce)) {
+                       zend_error_noreturn(E_ERROR,
+                               "Non-static method %s::%s() cannot be called statically, "
+                               "assuming $this from incompatible context",
+                               fbc->common.scope->name->val, fbc->common.function_name->val);
                }
        }
 
@@ -6052,24 +6052,24 @@ static int ZEND_FASTCALL  ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER
                        object = Z_OBJ(EX(This));
                        GC_REFCOUNT(object)++;
                }
-               if (!object ||
-                   !instanceof_function(object->ce, ce)) {
-                   /* We are calling method of the other (incompatible) class,
-                      but passing $this. This is done for compatibility with php-4. */
+               if (!object) {
                        if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
-                               zend_error(
-                                       object ? E_DEPRECATED : E_STRICT,
-                                       "Non-static method %s::%s() should not be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* We allow calling userland non-static methods without $this */
+                               zend_error(E_STRICT,
+                                       "Non-static method %s::%s() should not be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        } else {
-                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
-                               zend_error_noreturn(
-                                       E_ERROR,
-                                       "Non-static method %s::%s() cannot be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* An internal function assumes $this is present and won't check that.
+                                * So PHP would crash by allowing the call. */
+                               zend_error_noreturn(E_ERROR,
+                                       "Non-static method %s::%s() cannot be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        }
+               } else if (!instanceof_function(object->ce, ce)) {
+                       zend_error_noreturn(E_ERROR,
+                               "Non-static method %s::%s() cannot be called statically, "
+                               "assuming $this from incompatible context",
+                               fbc->common.scope->name->val, fbc->common.function_name->val);
                }
        }
 
@@ -7127,24 +7127,24 @@ static int ZEND_FASTCALL  ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN
                        object = Z_OBJ(EX(This));
                        GC_REFCOUNT(object)++;
                }
-               if (!object ||
-                   !instanceof_function(object->ce, ce)) {
-                   /* We are calling method of the other (incompatible) class,
-                      but passing $this. This is done for compatibility with php-4. */
+               if (!object) {
                        if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
-                               zend_error(
-                                       object ? E_DEPRECATED : E_STRICT,
-                                       "Non-static method %s::%s() should not be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* We allow calling userland non-static methods without $this */
+                               zend_error(E_STRICT,
+                                       "Non-static method %s::%s() should not be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        } else {
-                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
-                               zend_error_noreturn(
-                                       E_ERROR,
-                                       "Non-static method %s::%s() cannot be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* An internal function assumes $this is present and won't check that.
+                                * So PHP would crash by allowing the call. */
+                               zend_error_noreturn(E_ERROR,
+                                       "Non-static method %s::%s() cannot be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        }
+               } else if (!instanceof_function(object->ce, ce)) {
+                       zend_error_noreturn(E_ERROR,
+                               "Non-static method %s::%s() cannot be called statically, "
+                               "assuming $this from incompatible context",
+                               fbc->common.scope->name->val, fbc->common.function_name->val);
                }
        }
 
@@ -8265,24 +8265,24 @@ static int ZEND_FASTCALL  ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER
                        object = Z_OBJ(EX(This));
                        GC_REFCOUNT(object)++;
                }
-               if (!object ||
-                   !instanceof_function(object->ce, ce)) {
-                   /* We are calling method of the other (incompatible) class,
-                      but passing $this. This is done for compatibility with php-4. */
+               if (!object) {
                        if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
-                               zend_error(
-                                       object ? E_DEPRECATED : E_STRICT,
-                                       "Non-static method %s::%s() should not be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* We allow calling userland non-static methods without $this */
+                               zend_error(E_STRICT,
+                                       "Non-static method %s::%s() should not be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        } else {
-                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
-                               zend_error_noreturn(
-                                       E_ERROR,
-                                       "Non-static method %s::%s() cannot be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* An internal function assumes $this is present and won't check that.
+                                * So PHP would crash by allowing the call. */
+                               zend_error_noreturn(E_ERROR,
+                                       "Non-static method %s::%s() cannot be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        }
+               } else if (!instanceof_function(object->ce, ce)) {
+                       zend_error_noreturn(E_ERROR,
+                               "Non-static method %s::%s() cannot be called statically, "
+                               "assuming $this from incompatible context",
+                               fbc->common.scope->name->val, fbc->common.function_name->val);
                }
        }
 
@@ -13393,24 +13393,24 @@ static int ZEND_FASTCALL  ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE
                        object = Z_OBJ(EX(This));
                        GC_REFCOUNT(object)++;
                }
-               if (!object ||
-                   !instanceof_function(object->ce, ce)) {
-                   /* We are calling method of the other (incompatible) class,
-                      but passing $this. This is done for compatibility with php-4. */
+               if (!object) {
                        if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
-                               zend_error(
-                                       object ? E_DEPRECATED : E_STRICT,
-                                       "Non-static method %s::%s() should not be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* We allow calling userland non-static methods without $this */
+                               zend_error(E_STRICT,
+                                       "Non-static method %s::%s() should not be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        } else {
-                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
-                               zend_error_noreturn(
-                                       E_ERROR,
-                                       "Non-static method %s::%s() cannot be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* An internal function assumes $this is present and won't check that.
+                                * So PHP would crash by allowing the call. */
+                               zend_error_noreturn(E_ERROR,
+                                       "Non-static method %s::%s() cannot be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        }
+               } else if (!instanceof_function(object->ce, ce)) {
+                       zend_error_noreturn(E_ERROR,
+                               "Non-static method %s::%s() cannot be called statically, "
+                               "assuming $this from incompatible context",
+                               fbc->common.scope->name->val, fbc->common.function_name->val);
                }
        }
 
@@ -14882,24 +14882,24 @@ static int ZEND_FASTCALL  ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z
                        object = Z_OBJ(EX(This));
                        GC_REFCOUNT(object)++;
                }
-               if (!object ||
-                   !instanceof_function(object->ce, ce)) {
-                   /* We are calling method of the other (incompatible) class,
-                      but passing $this. This is done for compatibility with php-4. */
+               if (!object) {
                        if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
-                               zend_error(
-                                       object ? E_DEPRECATED : E_STRICT,
-                                       "Non-static method %s::%s() should not be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* We allow calling userland non-static methods without $this */
+                               zend_error(E_STRICT,
+                                       "Non-static method %s::%s() should not be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        } else {
-                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
-                               zend_error_noreturn(
-                                       E_ERROR,
-                                       "Non-static method %s::%s() cannot be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* An internal function assumes $this is present and won't check that.
+                                * So PHP would crash by allowing the call. */
+                               zend_error_noreturn(E_ERROR,
+                                       "Non-static method %s::%s() cannot be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        }
+               } else if (!instanceof_function(object->ce, ce)) {
+                       zend_error_noreturn(E_ERROR,
+                               "Non-static method %s::%s() cannot be called statically, "
+                               "assuming $this from incompatible context",
+                               fbc->common.scope->name->val, fbc->common.function_name->val);
                }
        }
 
@@ -16329,24 +16329,24 @@ static int ZEND_FASTCALL  ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_
                        object = Z_OBJ(EX(This));
                        GC_REFCOUNT(object)++;
                }
-               if (!object ||
-                   !instanceof_function(object->ce, ce)) {
-                   /* We are calling method of the other (incompatible) class,
-                      but passing $this. This is done for compatibility with php-4. */
+               if (!object) {
                        if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
-                               zend_error(
-                                       object ? E_DEPRECATED : E_STRICT,
-                                       "Non-static method %s::%s() should not be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* We allow calling userland non-static methods without $this */
+                               zend_error(E_STRICT,
+                                       "Non-static method %s::%s() should not be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        } else {
-                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
-                               zend_error_noreturn(
-                                       E_ERROR,
-                                       "Non-static method %s::%s() cannot be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* An internal function assumes $this is present and won't check that.
+                                * So PHP would crash by allowing the call. */
+                               zend_error_noreturn(E_ERROR,
+                                       "Non-static method %s::%s() cannot be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        }
+               } else if (!instanceof_function(object->ce, ce)) {
+                       zend_error_noreturn(E_ERROR,
+                               "Non-static method %s::%s() cannot be called statically, "
+                               "assuming $this from incompatible context",
+                               fbc->common.scope->name->val, fbc->common.function_name->val);
                }
        }
 
@@ -17766,24 +17766,24 @@ static int ZEND_FASTCALL  ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER(Z
                        object = Z_OBJ(EX(This));
                        GC_REFCOUNT(object)++;
                }
-               if (!object ||
-                   !instanceof_function(object->ce, ce)) {
-                   /* We are calling method of the other (incompatible) class,
-                      but passing $this. This is done for compatibility with php-4. */
+               if (!object) {
                        if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
-                               zend_error(
-                                       object ? E_DEPRECATED : E_STRICT,
-                                       "Non-static method %s::%s() should not be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* We allow calling userland non-static methods without $this */
+                               zend_error(E_STRICT,
+                                       "Non-static method %s::%s() should not be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        } else {
-                               /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
-                               zend_error_noreturn(
-                                       E_ERROR,
-                                       "Non-static method %s::%s() cannot be called statically%s",
-                                       fbc->common.scope->name->val, fbc->common.function_name->val,
-                                       object ? ", assuming $this from incompatible context" : "");
+                               /* An internal function assumes $this is present and won't check that.
+                                * So PHP would crash by allowing the call. */
+                               zend_error_noreturn(E_ERROR,
+                                       "Non-static method %s::%s() cannot be called statically",
+                                       fbc->common.scope->name->val, fbc->common.function_name->val);
                        }
+               } else if (!instanceof_function(object->ce, ce)) {
+                       zend_error_noreturn(E_ERROR,
+                               "Non-static method %s::%s() cannot be called statically, "
+                               "assuming $this from incompatible context",
+                               fbc->common.scope->name->val, fbc->common.function_name->val);
                }
        }