]> granicus.if.org Git - php/commitdiff
Fix $x = (bool)$x; for undefined with opcache
authorTyson Andre <tysonandre775@hotmail.com>
Fri, 15 Nov 2019 17:47:32 +0000 (12:47 -0500)
committerDmitry Stogov <dmitry@zend.com>
Mon, 18 Nov 2019 08:24:03 +0000 (11:24 +0300)
And `$x = !$x`

Noticed while working on GH-4912

The included test would not emit undefined variable errors in php 8.0
with opcache enabled. The command used:

```
php -d zend_extension=opcache.so --no-php-ini -d error_reporting=E_ALL \
    -d opcache.file_cache= -d opcache.enable_cli=1  test.php
```

Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/opcache/tests/bool_not_cv.phpt [new file with mode: 0644]

index e4431e6a3a012730adf79422db4d4dbbccba07f7..ed84d17bb8f3ab9f76c147579881be27009da393 100644 (file)
@@ -758,8 +758,10 @@ ZEND_VM_HANDLER(13, ZEND_BOOL_NOT, CONST|TMPVAR|CV, ANY)
        if (Z_TYPE_INFO_P(val) == IS_TRUE) {
                ZVAL_FALSE(EX_VAR(opline->result.var));
        } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+               /* The result and op1 can be the same cv zval */
+               const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
                ZVAL_TRUE(EX_VAR(opline->result.var));
-               if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+               if (OP1_TYPE == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
                        SAVE_OPLINE();
                        GET_OP1_UNDEF_CV(val, BP_VAR_R);
                        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -4755,8 +4757,10 @@ ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMPVAR|CV, ANY)
        if (Z_TYPE_INFO_P(val) == IS_TRUE) {
                ZVAL_TRUE(EX_VAR(opline->result.var));
        } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+               /* The result and op1 can be the same cv zval */
+               const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
                ZVAL_FALSE(EX_VAR(opline->result.var));
-               if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+               if (OP1_TYPE == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
                        SAVE_OPLINE();
                        GET_OP1_UNDEF_CV(val, BP_VAR_R);
                        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
index d313e9502da4cff4eac3d72d28762d761f0e7ebb..3f975dec0b6d93aba5d340a7e941ba8078ba8191 100644 (file)
@@ -2653,8 +2653,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CONST_HANDLER(ZE
        if (Z_TYPE_INFO_P(val) == IS_TRUE) {
                ZVAL_FALSE(EX_VAR(opline->result.var));
        } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+               /* The result and op1 can be the same cv zval */
+               const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
                ZVAL_TRUE(EX_VAR(opline->result.var));
-               if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+               if (IS_CONST == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
                        SAVE_OPLINE();
                        GET_OP1_UNDEF_CV(val, BP_VAR_R);
                        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -3185,8 +3187,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_O
        if (Z_TYPE_INFO_P(val) == IS_TRUE) {
                ZVAL_TRUE(EX_VAR(opline->result.var));
        } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+               /* The result and op1 can be the same cv zval */
+               const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
                ZVAL_FALSE(EX_VAR(opline->result.var));
-               if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+               if (IS_CONST == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
                        SAVE_OPLINE();
                        GET_OP1_UNDEF_CV(val, BP_VAR_R);
                        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -32866,8 +32870,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_
        if (Z_TYPE_INFO_P(val) == IS_TRUE) {
                ZVAL_FALSE(EX_VAR(opline->result.var));
        } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+               /* The result and op1 can be the same cv zval */
+               const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
                ZVAL_TRUE(EX_VAR(opline->result.var));
-               if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+               if (IS_CV == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
                        SAVE_OPLINE();
                        GET_OP1_UNDEF_CV(val, BP_VAR_R);
                        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -33704,8 +33710,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCO
        if (Z_TYPE_INFO_P(val) == IS_TRUE) {
                ZVAL_TRUE(EX_VAR(opline->result.var));
        } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+               /* The result and op1 can be the same cv zval */
+               const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
                ZVAL_FALSE(EX_VAR(opline->result.var));
-               if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+               if (IS_CV == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
                        SAVE_OPLINE();
                        GET_OP1_UNDEF_CV(val, BP_VAR_R);
                        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -48537,8 +48545,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER(Z
        if (Z_TYPE_INFO_P(val) == IS_TRUE) {
                ZVAL_FALSE(EX_VAR(opline->result.var));
        } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+               /* The result and op1 can be the same cv zval */
+               const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
                ZVAL_TRUE(EX_VAR(opline->result.var));
-               if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+               if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
                        SAVE_OPLINE();
                        GET_OP1_UNDEF_CV(val, BP_VAR_R);
                        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
@@ -48801,8 +48811,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BOOL_SPEC_TMPVAR_HANDLER(ZEND_
        if (Z_TYPE_INFO_P(val) == IS_TRUE) {
                ZVAL_TRUE(EX_VAR(opline->result.var));
        } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) {
+               /* The result and op1 can be the same cv zval */
+               const uint32_t orig_val_type = Z_TYPE_INFO_P(val);
                ZVAL_FALSE(EX_VAR(opline->result.var));
-               if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) {
+               if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) {
                        SAVE_OPLINE();
                        GET_OP1_UNDEF_CV(val, BP_VAR_R);
                        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
diff --git a/ext/opcache/tests/bool_not_cv.phpt b/ext/opcache/tests/bool_not_cv.phpt
new file mode 100644 (file)
index 0000000..ed3cf83
--- /dev/null
@@ -0,0 +1,34 @@
+--TEST--
+$v = !$v/(bool)$v checks for undefined variables
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.file_cache_only=0
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+function undef_negation() {
+    echo "In undef_negation\n";
+    $v = !$v;
+    var_export($v);
+    echo "\n";
+}
+function undef_bool_cast() {
+    echo "In undef_bool_cast\n";
+    $v = (bool)$v;
+    var_export($v);
+    echo "\n";
+}
+undef_negation();
+undef_bool_cast();
+?>
+--EXPECTF--
+In undef_negation
+
+Notice: Undefined variable: v in %s on line 4
+true
+In undef_bool_cast
+
+Notice: Undefined variable: v in %s on line 10
+false