Skip to content

Commit 277ca7f

Browse files
committed
Function fallback
1 parent e0b73dc commit 277ca7f

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

Zend/zend_compile.c

+44-1
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,8 @@ void zend_file_context_begin(zend_file_context *prev_context) /* {{{ */
406406
FC(in_namespace) = 0;
407407
FC(has_bracketed_namespaces) = 0;
408408
FC(declarables).ticks = 0;
409+
FC(declarables).error_on_unqualified_function = false;
410+
FC(declarables).force_global_function_fallback = false;
409411
zend_hash_init(&FC(seen_symbols), 8, NULL, NULL, 0);
410412
}
411413
/* }}} */
@@ -1128,6 +1130,12 @@ static zend_string *zend_resolve_non_class_name(
11281130
}
11291131
}
11301132

1133+
if (FC(declarables).force_global_function_fallback && !compound) {
1134+
*is_fully_qualified = 1;
1135+
1136+
return zend_string_copy(name);
1137+
}
1138+
11311139
return zend_prefix_with_ns(name);
11321140
}
11331141
/* }}} */
@@ -5138,6 +5146,17 @@ static void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{
51385146
&& !is_callable_convert) {
51395147
zend_compile_assert(result, zend_ast_get_list(args_ast), Z_STR(name_node.u.constant), NULL, ast->lineno);
51405148
} else {
5149+
if (FC(declarables).error_on_unqualified_function) {
5150+
zend_error_noreturn_unchecked(E_COMPILE_ERROR,
5151+
"Unqualified function name \"%S\", use either \"namespace\\%S\" or \"\\%S\", or explicitly import the function with either \"use function %S\\%S;\" or \"use function %S;\"",
5152+
zend_ast_get_str(name_ast),
5153+
zend_ast_get_str(name_ast),
5154+
zend_ast_get_str(name_ast),
5155+
FC(current_namespace),
5156+
zend_ast_get_str(name_ast),
5157+
zend_ast_get_str(name_ast)
5158+
);
5159+
}
51415160
zend_compile_ns_call(result, &name_node, args_ast, ast->lineno, type);
51425161
}
51435162
return;
@@ -6878,7 +6897,31 @@ static void zend_compile_declare(zend_ast *ast) /* {{{ */
68786897
zend_error_noreturn(E_COMPILE_ERROR, "declare(%s) value must be a literal", ZSTR_VAL(name));
68796898
}
68806899

6881-
if (zend_string_equals_literal_ci(name, "ticks")) {
6900+
if (zend_string_equals_literal_ci(name, "error_on_unqualified_function")) {
6901+
zval value_zv;
6902+
zend_const_expr_to_zval(&value_zv, value_ast_ptr, /* allow_dynamic */ false);
6903+
if (Z_TYPE(value_zv) != IS_LONG || (Z_LVAL(value_zv) != 0 && Z_LVAL(value_zv) != 1)) {
6904+
zend_error_noreturn(E_COMPILE_ERROR, "error_on_unqualified_function declaration must have 0 or 1 as its value");
6905+
}
6906+
FC(declarables).force_global_function_fallback = Z_LVAL(value_zv) == 1;
6907+
zval_ptr_dtor_nogc(&value_zv);
6908+
6909+
if (FC(declarables).force_global_function_fallback) {
6910+
zend_error_noreturn(E_COMPILE_ERROR, "force_global_function_fallback declaration and error_on_unqualified_function declaration are mutually exclusive");
6911+
}
6912+
} else if (zend_string_equals_literal_ci(name, "force_global_function_fallback")) {
6913+
zval value_zv;
6914+
zend_const_expr_to_zval(&value_zv, value_ast_ptr, /* allow_dynamic */ false);
6915+
if (Z_TYPE(value_zv) != IS_LONG || (Z_LVAL(value_zv) != 0 && Z_LVAL(value_zv) != 1)) {
6916+
zend_error_noreturn(E_COMPILE_ERROR, "force_global_function_fallback declaration must have 0 or 1 as its value");
6917+
}
6918+
FC(declarables).force_global_function_fallback = Z_LVAL(value_zv) == 1;
6919+
zval_ptr_dtor_nogc(&value_zv);
6920+
6921+
if (FC(declarables).error_on_unqualified_function) {
6922+
zend_error_noreturn(E_COMPILE_ERROR, "force_global_function_fallback declaration and error_on_unqualified_function declaration are mutually exclusive");
6923+
}
6924+
} else if (zend_string_equals_literal_ci(name, "ticks")) {
68826925
zval value_zv;
68836926
zend_const_expr_to_zval(&value_zv, value_ast_ptr, /* allow_dynamic */ false);
68846927
FC(declarables).ticks = zval_get_long(&value_zv);

Zend/zend_compile.h

+2
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ static zend_always_inline znode *zend_ast_get_znode(zend_ast *ast) {
104104

105105
typedef struct _zend_declarables {
106106
zend_long ticks;
107+
bool error_on_unqualified_function;
108+
bool force_global_function_fallback;
107109
} zend_declarables;
108110

109111
/* Compilation context that is different for each file, but shared between op arrays. */

0 commit comments

Comments
 (0)