From: Nikita Popov Date: Wed, 27 Mar 2019 12:02:28 +0000 (+0100) Subject: Fix lineno for more inheritance errors X-Git-Tag: php-7.4.0alpha1~660 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d1e5006c1487c0df1333564c3fdcc0528e1da394;p=php Fix lineno for more inheritance errors And also include explicit linenos in tests. --- diff --git a/Zend/tests/bug61970_1.phpt b/Zend/tests/bug61970_1.phpt index 15dc781385..417eaa0aef 100644 --- a/Zend/tests/bug61970_1.phpt +++ b/Zend/tests/bug61970_1.phpt @@ -11,4 +11,4 @@ class Bar extends Foo { protected function __construct(){} } --EXPECTF-- -Fatal error: Access level to Bar::__construct() must be public (as in class Foo) in %s +Fatal error: Access level to Bar::__construct() must be public (as in class Foo) in %s on line 8 diff --git a/Zend/tests/bug61970_2.phpt b/Zend/tests/bug61970_2.phpt index d1e11e9407..3e4b5222be 100644 --- a/Zend/tests/bug61970_2.phpt +++ b/Zend/tests/bug61970_2.phpt @@ -15,4 +15,4 @@ class Baz extends Bar { protected function __construct(){} } --EXPECTF-- -Fatal error: Access level to Baz::__construct() must be public (as in class Bar) in %s +Fatal error: Access level to Baz::__construct() must be public (as in class Bar) in %s on line 12 diff --git a/Zend/tests/bug62814.phpt b/Zend/tests/bug62814.phpt index 6646aa283f..c08360dd95 100644 --- a/Zend/tests/bug62814.phpt +++ b/Zend/tests/bug62814.phpt @@ -17,4 +17,4 @@ class C extends B { ?> --EXPECTF-- -Fatal error: Access level to C::test() must be protected (as in class B) or weaker in %s on line %d +Fatal error: Access level to C::test() must be protected (as in class B) or weaker in %s on line 12 diff --git a/Zend/tests/inter_007.phpt b/Zend/tests/inter_007.phpt index 610210a7da..fa7c368a5e 100644 --- a/Zend/tests/inter_007.phpt +++ b/Zend/tests/inter_007.phpt @@ -17,4 +17,4 @@ interface a extends d, w { } ?> --EXPECTF-- -Fatal error: Cannot make non static method c::B() static in class d in %s on line %d +Fatal error: Cannot make non static method c::B() static in class d in %s on line 4 diff --git a/Zend/tests/magic_methods_008.phpt b/Zend/tests/magic_methods_008.phpt index 61c4fa0a29..25731516e6 100644 --- a/Zend/tests/magic_methods_008.phpt +++ b/Zend/tests/magic_methods_008.phpt @@ -16,4 +16,4 @@ class a extends b { --EXPECTF-- Warning: The magic method __set() must have public visibility and cannot be static in %s on line %d -Fatal error: Access level to a::__set() must be public (as in class b) in %s on line %d +Fatal error: Access level to a::__set() must be public (as in class b) in %s on line 8 diff --git a/Zend/zend.c b/Zend/zend.c index 721a097117..36f47ee08f 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1473,6 +1473,24 @@ ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) { va_end(args); } +ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_at_noreturn( + int type, const char *filename, uint32_t lineno, const char *format, ...) +{ + va_list args; + + if (!filename) { + uint32_t dummy_lineno; + get_filename_lineno(type, &filename, &dummy_lineno); + } + + va_start(args, format); + zend_error_va_list(type, filename, lineno, format, args); + va_end(args); + /* Should never reach this. */ + abort(); +} +/* }}} */ + ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...) { const char *filename; diff --git a/Zend/zend.h b/Zend/zend.h index 70c3d82c83..86b10ea58e 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -296,6 +296,7 @@ ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) ZEND_ATTRI ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); /* If filename is NULL the default filename is used. */ ZEND_API ZEND_COLD void zend_error_at(int type, const char *filename, uint32_t lineno, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 4, 5); +ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_at_noreturn(int type, const char *filename, uint32_t lineno, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 4, 5); ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); ZEND_API ZEND_COLD void zend_type_error(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2); diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index f7cb37e2df..72bc9cfaae 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -546,13 +546,19 @@ static ZEND_COLD zend_string *zend_get_function_declaration(const zend_function } /* }}} */ +static zend_always_inline uint32_t func_lineno(zend_function *fn) { + return fn->common.type == ZEND_USER_FUNCTION ? fn->op_array.line_start : 0; +} + static void do_inheritance_check_on_method(zend_function *child, zend_function *parent, zend_class_entry *ce, zval *child_zv) /* {{{ */ { uint32_t child_flags; uint32_t parent_flags = parent->common.fn_flags; if (UNEXPECTED(parent_flags & ZEND_ACC_FINAL)) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot override final method %s::%s()", ZEND_FN_SCOPE_NAME(parent), ZSTR_VAL(child->common.function_name)); + zend_error_at_noreturn(E_COMPILE_ERROR, NULL, func_lineno(child), + "Cannot override final method %s::%s()", + ZEND_FN_SCOPE_NAME(parent), ZSTR_VAL(child->common.function_name)); } child_flags = child->common.fn_flags; @@ -560,15 +566,21 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function * */ if (UNEXPECTED((child_flags & ZEND_ACC_STATIC) != (parent_flags & ZEND_ACC_STATIC))) { if (child_flags & ZEND_ACC_STATIC) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot make non static method %s::%s() static in class %s", ZEND_FN_SCOPE_NAME(parent), ZSTR_VAL(child->common.function_name), ZEND_FN_SCOPE_NAME(child)); + zend_error_at_noreturn(E_COMPILE_ERROR, NULL, func_lineno(child), + "Cannot make non static method %s::%s() static in class %s", + ZEND_FN_SCOPE_NAME(parent), ZSTR_VAL(child->common.function_name), ZEND_FN_SCOPE_NAME(child)); } else { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot make static method %s::%s() non static in class %s", ZEND_FN_SCOPE_NAME(parent), ZSTR_VAL(child->common.function_name), ZEND_FN_SCOPE_NAME(child)); + zend_error_at_noreturn(E_COMPILE_ERROR, NULL, func_lineno(child), + "Cannot make static method %s::%s() non static in class %s", + ZEND_FN_SCOPE_NAME(parent), ZSTR_VAL(child->common.function_name), ZEND_FN_SCOPE_NAME(child)); } } /* Disallow making an inherited method abstract. */ if (UNEXPECTED((child_flags & ZEND_ACC_ABSTRACT) > (parent_flags & ZEND_ACC_ABSTRACT))) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot make non abstract method %s::%s() abstract in class %s", ZEND_FN_SCOPE_NAME(parent), ZSTR_VAL(child->common.function_name), ZEND_FN_SCOPE_NAME(child)); + zend_error_at_noreturn(E_COMPILE_ERROR, NULL, func_lineno(child), + "Cannot make non abstract method %s::%s() abstract in class %s", + ZEND_FN_SCOPE_NAME(parent), ZSTR_VAL(child->common.function_name), ZEND_FN_SCOPE_NAME(child)); } if (parent_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_CHANGED)) { @@ -615,7 +627,9 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function * } /* Prevent derived classes from restricting access that was available in parent classes (except deriving from non-abstract ctors) */ if ((child_flags & ZEND_ACC_PPP_MASK) > (parent_flags & ZEND_ACC_PPP_MASK)) { - zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::%s() must be %s (as in class %s)%s", ZEND_FN_SCOPE_NAME(child), ZSTR_VAL(child->common.function_name), zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); + zend_error_at_noreturn(E_COMPILE_ERROR, NULL, func_lineno(child), + "Access level to %s::%s() must be %s (as in class %s)%s", + ZEND_FN_SCOPE_NAME(child), ZSTR_VAL(child->common.function_name), zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); } if (UNEXPECTED(!zend_do_perform_implementation_check(child, parent))) { @@ -639,8 +653,7 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function * error_level = E_WARNING; error_verb = "should"; } - zend_error_at(error_level, NULL, - child->common.type == ZEND_USER_FUNCTION ? child->op_array.line_start : 0, + zend_error_at(error_level, NULL, func_lineno(child), "Declaration of %s %s be compatible with %s", ZSTR_VAL(child_prototype), error_verb, ZSTR_VAL(method_prototype)); zend_string_efree(child_prototype); diff --git a/tests/classes/clone_005.phpt b/tests/classes/clone_005.phpt index bfe4d66d6f..f759221480 100644 --- a/tests/classes/clone_005.phpt +++ b/tests/classes/clone_005.phpt @@ -16,4 +16,4 @@ class test extends base { ?> --EXPECTF-- -Fatal error: Cannot override final method base::__clone() in %sclone_005.php on line %d +Fatal error: Cannot override final method base::__clone() in %sclone_005.php on line 11 diff --git a/tests/classes/final_ctor3.phpt b/tests/classes/final_ctor3.phpt index b34996c979..b0156ef294 100644 --- a/tests/classes/final_ctor3.phpt +++ b/tests/classes/final_ctor3.phpt @@ -12,4 +12,4 @@ Ensure implicit final inherited old-style constructor cannot be overridden. --EXPECTF-- Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; A has a deprecated constructor in %s on line %d -Fatal error: Cannot override final method A::A() in %s on line %d +Fatal error: Cannot override final method A::A() in %s on line 6 diff --git a/tests/classes/final_redeclare.phpt b/tests/classes/final_redeclare.phpt index bdcbf3c86c..d3d53c5dc7 100644 --- a/tests/classes/final_redeclare.phpt +++ b/tests/classes/final_redeclare.phpt @@ -20,4 +20,4 @@ class fail extends pass { echo "Done\n"; // Shouldn't be displayed ?> --EXPECTF-- -Fatal error: Cannot override final method pass::show() in %s on line %d +Fatal error: Cannot override final method pass::show() in %s on line 12 diff --git a/tests/classes/static_mix_1.phpt b/tests/classes/static_mix_1.phpt index 70740d2336..8dead36856 100644 --- a/tests/classes/static_mix_1.phpt +++ b/tests/classes/static_mix_1.phpt @@ -21,4 +21,4 @@ fail::show(); echo "Done\n"; // shouldn't be displayed ?> --EXPECTF-- -Fatal error: Cannot make static method pass::show() non static in class fail in %s on line %d +Fatal error: Cannot make static method pass::show() non static in class fail in %s on line 10 diff --git a/tests/classes/static_mix_2.phpt b/tests/classes/static_mix_2.phpt index ec657c0d5e..bbf6f9c1dd 100644 --- a/tests/classes/static_mix_2.phpt +++ b/tests/classes/static_mix_2.phpt @@ -22,4 +22,4 @@ fail::show(); echo "Done\n"; // shouldn't be displayed ?> --EXPECTF-- -Fatal error: Cannot make non static method pass::show() static in class fail in %s on line %d +Fatal error: Cannot make non static method pass::show() static in class fail in %s on line 10 diff --git a/tests/classes/visibility_000a.phpt b/tests/classes/visibility_000a.phpt index 0dd86aa182..00e918ad30 100644 --- a/tests/classes/visibility_000a.phpt +++ b/tests/classes/visibility_000a.phpt @@ -28,4 +28,4 @@ class fail extends same { echo "Done\n"; // shouldn't be displayed ?> --EXPECTF-- -Fatal error: Access level to fail::f0() must be public (as in class same) in %s on line %d +Fatal error: Access level to fail::f0() must be public (as in class same) in %s on line 22 diff --git a/tests/classes/visibility_000b.phpt b/tests/classes/visibility_000b.phpt index f6ac466345..aeb3078b72 100644 --- a/tests/classes/visibility_000b.phpt +++ b/tests/classes/visibility_000b.phpt @@ -28,4 +28,4 @@ class fail extends same { echo "Done\n"; // shouldn't be displayed ?> --EXPECTF-- -Fatal error: Access level to fail::f0() must be public (as in class same) in %s on line %d +Fatal error: Access level to fail::f0() must be public (as in class same) in %s on line 22 diff --git a/tests/classes/visibility_001a.phpt b/tests/classes/visibility_001a.phpt index d749b5266a..50baf64d67 100644 --- a/tests/classes/visibility_001a.phpt +++ b/tests/classes/visibility_001a.phpt @@ -28,4 +28,4 @@ class fail extends same { echo "Done\n"; // shouldn't be displayed ?> --EXPECTF-- -Fatal error: Access level to fail::f1() must be public (as in class same) in %s on line %d +Fatal error: Access level to fail::f1() must be public (as in class same) in %s on line 22 diff --git a/tests/classes/visibility_001b.phpt b/tests/classes/visibility_001b.phpt index 27c39cf430..626b5303f8 100644 --- a/tests/classes/visibility_001b.phpt +++ b/tests/classes/visibility_001b.phpt @@ -28,4 +28,4 @@ class fail extends same { echo "Done\n"; // shouldn't be displayed ?> --EXPECTF-- -Fatal error: Access level to fail::f1() must be public (as in class same) in %s on line %d +Fatal error: Access level to fail::f1() must be public (as in class same) in %s on line 22 diff --git a/tests/classes/visibility_002a.phpt b/tests/classes/visibility_002a.phpt index ea86412cea..2fd402070d 100644 --- a/tests/classes/visibility_002a.phpt +++ b/tests/classes/visibility_002a.phpt @@ -28,4 +28,4 @@ class fail extends same { echo "Done\n"; // shouldn't be displayed ?> --EXPECTF-- -Fatal error: Access level to fail::f2() must be public (as in class same) in %s on line %d +Fatal error: Access level to fail::f2() must be public (as in class same) in %s on line 22 diff --git a/tests/classes/visibility_002b.phpt b/tests/classes/visibility_002b.phpt index 8116a3239b..a8b1c5e79e 100644 --- a/tests/classes/visibility_002b.phpt +++ b/tests/classes/visibility_002b.phpt @@ -28,4 +28,4 @@ class fail extends same { echo "Done\n"; // shouldn't be displayed ?> --EXPECTF-- -Fatal error: Access level to fail::f2() must be public (as in class same) in %s on line %d +Fatal error: Access level to fail::f2() must be public (as in class same) in %s on line 22 diff --git a/tests/classes/visibility_003b.phpt b/tests/classes/visibility_003b.phpt index 9b45aa3487..474e0df235 100644 --- a/tests/classes/visibility_003b.phpt +++ b/tests/classes/visibility_003b.phpt @@ -28,4 +28,4 @@ class fail extends same { echo "Done\n"; // shouldn't be displayed ?> --EXPECTF-- -Fatal error: Access level to fail::f3() must be protected (as in class same) or weaker in %s on line %d +Fatal error: Access level to fail::f3() must be protected (as in class same) or weaker in %s on line 22