Bug #81015 [Opn]: Opcache optimization assumes wrong part of ternary operator in if-condition

From: Date: Thu, 06 May 2021 04:17:55 +0000
Subject: Bug #81015 [Opn]: Opcache optimization assumes wrong part of ternary operator in if-condition
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-233710@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=81015&edit=1

 ID:                 81015
 User updated by:    redwormik at gmail dot com
 Reported by:        redwormik at gmail dot com
 Summary:            Opcache optimization assumes wrong part of ternary
                     operator in if-condition
 Status:             Open
 Type:               Bug
 Package:            opcache
 Operating System:   Alpine 3.13 (Docker)
 PHP Version:        8.0.5
 Block user comment: N
 Private report:     N

 New Comment:

Sorry, changed the output at last minute, but did not change the script. The condition should be
(the else-branch output changed):

	if ($enabled ? true : $value === null) {
		echo ($value ?? 'NULL') . "\n";
	} else {
		echo "INVALID " . ($value ?? 'NULL') . "\n";
	}


Previous Comments:
------------------------------------------------------------------------
[2021-05-06 04:14:41] redwormik at gmail dot com

Description:
------------
I have opcache enabled and opcache.optimization_level at least 0x000000b0 (bits 4, 5 and 8 all set,
other irrelevant).

When I compare a variable to NULL in a "false" part of a ternary operator in an
if-condition, the variable changes to NULL in the respective branch of the if-condition (i.e. if
comparison is === NULL, the variable changes to NULL in the if-branch; if comparison is !== NULL,
the variable changes to NULL in the else-branch), even though the ternary operator condition is
true.

Returning the value, changing the condition so it does not use ternary operator, moving the
NULL-equality out of the condition to a local variable or comparing to anything else other than NULL
all work as expected.

Test script:
---------------
<?php
declare(strict_types=1);

function ternary(bool $enabled, ?string $value): void
{
	// the "true" part is not as trivial in the real case
	if ($enabled ? true : $value === null) {
		echo ($value ?? 'NULL') . "\n";
	} else {
		echo "INVALID\n";
	}
}

ternary(true, 'value');
ternary(true, null);
ternary(false, 'value');
ternary(false, null);


Expected result:
----------------
value
NULL
INVALID value
NULL


Actual result:
--------------
NULL
NULL
INVALID value
NULL


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=81015&edit=1


Thread (5 messages)

« previous php.bugs (#233710) next »