From: Anthony Ferrara Date: Thu, 19 Mar 2015 17:51:24 +0000 (-0400) Subject: Add support and tests for null constant default values. Refactor complex conditionals... X-Git-Tag: PRE_PHP7_NSAPI_REMOVAL~573^2~11^2~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=62fc556764a6a4b7ed010d09b2d8baed6c2ed01b;p=php Add support and tests for null constant default values. Refactor complex conditionals into an extracted function for clarity and code-reuse --- diff --git a/Zend/tests/typehints/scalar_constant_defaults.phpt b/Zend/tests/typehints/scalar_constant_defaults.phpt index b04c079ffc..4441022e16 100644 --- a/Zend/tests/typehints/scalar_constant_defaults.phpt +++ b/Zend/tests/typehints/scalar_constant_defaults.phpt @@ -9,6 +9,7 @@ const STRING_VAL = "this is a test"; const INT_ADD_VAL = 10 + 15; const FLOAT_ADD_VAL = 10.5 + 0.2; const STRING_ADD_VAL = "this" . " is a test"; +const NULL_VAL = null; function int_val(int $a = INT_VAL): int { return $a; @@ -34,6 +35,10 @@ function string_add_val(string $a = STRING_ADD_VAL): string { return $a; } +function int_val_default_null(int $a = NULL_VAL) { + return $a; +} + echo "Testing int val" . PHP_EOL; var_dump(int_val()); @@ -52,6 +57,12 @@ var_dump(float_add_val()); echo "Testing string add val" . PHP_EOL; var_dump(string_add_val()); +echo "Testing int with default null constant" . PHP_EOL; +var_dump(int_val_default_null()); + +echo "Testing int with null null constant" . PHP_EOL; +var_dump(int_val_default_null(null)); + ?> --EXPECTF-- Testing int val @@ -65,4 +76,8 @@ int(25) Testing float add val float(10.7) Testing string add val -string(14) "this is a test" \ No newline at end of file +string(14) "this is a test" +Testing int with default null constant +NULL +Testing int with null null constant +NULL \ No newline at end of file diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 99bfdae89e..c622157b46 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -698,6 +698,20 @@ static zend_bool zend_verify_scalar_type_hint(zend_uchar type_hint, zval *arg, z } } +static inline int zend_verify_scalar_type_error(zend_uchar type_hint, zend_uchar allow_null, zval *arg, zval *default_value, zend_bool strict) +{ + if (UNEXPECTED(!ZEND_SAME_FAKE_TYPE(type_hint, Z_TYPE_P(arg)))) { + if (Z_TYPE_P(arg) == IS_NULL) { + if (!allow_null && (!default_value || !is_null_constant(default_value))) { + return 1; + } + } else if (!zend_verify_scalar_type_hint(type_hint, arg, strict)) { + return 1; + } + } + return 0; +} + static void zend_verify_internal_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, zend_bool strict) { zend_internal_arg_info *cur_arg_info; @@ -735,12 +749,8 @@ static void zend_verify_internal_arg_type(zend_function *zf, uint32_t arg_num, z if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL) && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) { zend_verify_arg_error(zf, arg_num, "be callable", "", zend_zval_type_name(arg), "", arg); } - } else if (UNEXPECTED(!ZEND_SAME_FAKE_TYPE(cur_arg_info->type_hint, Z_TYPE_P(arg)))) { - if ((Z_TYPE_P(arg) == IS_NULL && !cur_arg_info->allow_null) - || (Z_TYPE_P(arg) != IS_NULL && !zend_verify_scalar_type_hint(cur_arg_info->type_hint, arg, strict))) { - - zend_verify_arg_error(zf, arg_num, "be of the type ", zend_get_type_by_const(cur_arg_info->type_hint), zend_zval_type_name(arg), "", arg); - } + } else if (UNEXPECTED(zend_verify_scalar_type_error(cur_arg_info->type_hint, cur_arg_info->allow_null, arg, NULL, strict))) { + zend_verify_arg_error(zf, arg_num, "be of the type ", zend_get_type_by_const(cur_arg_info->type_hint), zend_zval_type_name(arg), "", arg); } } } @@ -782,12 +792,8 @@ static void zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL) && (Z_TYPE_P(arg) != IS_NULL || !(cur_arg_info->allow_null || (default_value && is_null_constant(default_value))))) { zend_verify_arg_error(zf, arg_num, "be callable", "", zend_zval_type_name(arg), "", arg); } - } else if (UNEXPECTED(!ZEND_SAME_FAKE_TYPE(cur_arg_info->type_hint, Z_TYPE_P(arg)))) { - if ((Z_TYPE_P(arg) == IS_NULL && !cur_arg_info->allow_null) - || (Z_TYPE_P(arg) != IS_NULL && !zend_verify_scalar_type_hint(cur_arg_info->type_hint, arg, strict))) { - - zend_verify_arg_error(zf, arg_num, "be of the type ", zend_get_type_by_const(cur_arg_info->type_hint), zend_zval_type_name(arg), "", arg); - } + } else if (UNEXPECTED(zend_verify_scalar_type_error(cur_arg_info->type_hint, cur_arg_info->allow_null, arg, default_value, strict))) { + zend_verify_arg_error(zf, arg_num, "be of the type ", zend_get_type_by_const(cur_arg_info->type_hint), zend_zval_type_name(arg), "", arg); } } } @@ -916,13 +922,9 @@ static int zend_verify_internal_return_type(zend_function *zf, zval *ret, zend_b zend_verify_internal_return_error(zf, "be callable", "", zend_zval_type_name(ret), ""); return 0; } - } else if (UNEXPECTED(!ZEND_SAME_FAKE_TYPE(ret_info->type_hint, Z_TYPE_P(ret)))) { - if ((Z_TYPE_P(ret) == IS_NULL && !ret_info->allow_null) - || (Z_TYPE_P(ret) != IS_NULL && !zend_verify_scalar_type_hint(ret_info->type_hint, ret, strict))) { - - zend_verify_internal_return_error(zf, "be of the type ", zend_get_type_by_const(ret_info->type_hint), zend_zval_type_name(ret), ""); - return 0; - } + } else if (UNEXPECTED(zend_verify_scalar_type_error(ret_info->type_hint, ret_info->allow_null, ret, NULL, strict))) { + zend_verify_internal_return_error(zf, "be of the type ", zend_get_type_by_const(ret_info->type_hint), zend_zval_type_name(ret), ""); + return 0; } } return 1; @@ -956,12 +958,8 @@ static void zend_verify_return_type(zend_function *zf, zval *ret, zend_bool stri if (!zend_is_callable(ret, IS_CALLABLE_CHECK_SILENT, NULL) && (Z_TYPE_P(ret) != IS_NULL || !ret_info->allow_null)) { zend_verify_return_error(zf, "be callable", "", zend_zval_type_name(ret), ""); } - } else if (UNEXPECTED(!ZEND_SAME_FAKE_TYPE(ret_info->type_hint, Z_TYPE_P(ret)))) { - if ((Z_TYPE_P(ret) == IS_NULL && !ret_info->allow_null) - || (Z_TYPE_P(ret) != IS_NULL && !zend_verify_scalar_type_hint(ret_info->type_hint, ret, strict))) { - - zend_verify_return_error(zf, "be of the type ", zend_get_type_by_const(ret_info->type_hint), zend_zval_type_name(ret), ""); - } + } else if (UNEXPECTED(zend_verify_scalar_type_error(ret_info->type_hint, ret_info->allow_null, ret, NULL, strict))) { + zend_verify_return_error(zf, "be of the type ", zend_get_type_by_const(ret_info->type_hint), zend_zval_type_name(ret), ""); } } }