summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2006-09-26 10:31:04 +0000
committerDmitry Stogov <dmitry@php.net>2006-09-26 10:31:04 +0000
commit798d93c4daa3f417314e1107124bc820ae73bdfc (patch)
treed61cb778c921241dd7fc353f9368bf40af564d77
parent59d0c16391fd35d72550c270ec90ed12789bba3c (diff)
downloadphp-git-798d93c4daa3f417314e1107124bc820ae73bdfc.tar.gz
Fixed bug #38808 ("maybe ref" issue for current() and others)
-rwxr-xr-xZend/tests/bug38808.phpt17
-rw-r--r--Zend/zend_compile.h51
-rw-r--r--Zend/zend_vm_def.h2
-rw-r--r--Zend/zend_vm_execute.h8
4 files changed, 39 insertions, 39 deletions
diff --git a/Zend/tests/bug38808.phpt b/Zend/tests/bug38808.phpt
new file mode 100755
index 0000000000..0fc4bfecdc
--- /dev/null
+++ b/Zend/tests/bug38808.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #38808 ("maybe ref" issue for current() and others)
+--FILE--
+<?php
+$current = "current";
+$next = "next";
+
+$b = array(1=>'one', 2=>'two');
+$a =& $b;
+
+echo $current($a)."\n";
+$next($a);
+echo $current($a)."\n";
+?>
+--EXPECT--
+one
+two \ No newline at end of file
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 6dc24704ef..df0bf24c6a 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -691,40 +691,23 @@ int zendlex(znode *zendlval TSRMLS_DC);
#define ZEND_SEND_BY_REF 1
#define ZEND_SEND_PREFER_REF 2
-/* Lost In Stupid Parentheses */
-#define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \
- ( \
- zf \
- && ((zend_function *) zf)->common.arg_info \
- && \
- ( \
- ( \
- arg_num<=((zend_function *) zf)->common.num_args \
- && ((zend_function *) zf)->common.arg_info[arg_num-1].pass_by_reference == ZEND_SEND_BY_REF \
- ) \
- || ( \
- arg_num>((zend_function *) zf)->common.num_args \
- && ((zend_function *) zf)->common.pass_rest_by_reference == ZEND_SEND_BY_REF \
- ) \
- ) \
- )
-
-#define ARG_MAY_BE_SENT_BY_REF(zf, arg_num) \
- ( \
- zf \
- && ((zend_function *) zf)->common.arg_info \
- && \
- ( \
- ( \
- arg_num<=((zend_function *) zf)->common.num_args \
- && ((zend_function *) zf)->common.arg_info[arg_num-1].pass_by_reference == ZEND_SEND_PREFER_REF \
- ) \
- || ( \
- arg_num>((zend_function *) zf)->common.num_args \
- && ((zend_function *) zf)->common.pass_rest_by_reference == ZEND_SEND_PREFER_REF \
- ) \
- ) \
- )
+#define ARG_SEND_TYPE(zf, arg_num) \
+ ((zf) ? \
+ ((((zend_function*)(zf))->common.arg_info && \
+ arg_num<=((zend_function*)(zf))->common.num_args) ? \
+ ((zend_function *)(zf))->common.arg_info[arg_num-1].pass_by_reference : \
+ ((zend_function *)(zf))->common.pass_rest_by_reference) : \
+ ZEND_SEND_BY_VAL)
+
+#define ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \
+ (ARG_SEND_TYPE(zf, arg_num) == ZEND_SEND_BY_REF)
+
+#define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \
+ (ARG_SEND_TYPE(zf, arg_num) & (ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF))
+
+#define ARG_MAY_BE_SENT_BY_REF(zf, arg_num) \
+ (ARG_SEND_TYPE(zf, arg_num) == ZEND_SEND_PREFER_REF)
+
#define ZEND_RETURN_VAL 0
#define ZEND_RETURN_REF 1
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 9fcd1284aa..dca5b9c56e 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2202,7 +2202,7 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP|VAR|CV, ANY)
{
zend_op *opline = EX(opline);
if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
- && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
+ && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num);
}
{
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index d2afe00271..99277f2b18 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1744,7 +1744,7 @@ static int ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
- && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
+ && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num);
}
{
@@ -4338,7 +4338,7 @@ static int ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
- && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
+ && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num);
}
{
@@ -7439,7 +7439,7 @@ static int ZEND_SEND_VAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
- && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
+ && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num);
}
{
@@ -19980,7 +19980,7 @@ static int ZEND_SEND_VAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_op *opline = EX(opline);
if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
- && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
+ && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) {
zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.u.opline_num);
}
{