php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77257 value of variable assigned in a switch() construct gets lost
Submitted: 2018-12-06 20:35 UTC Modified: 2019-01-02 08:09 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:0 (0.0%)
From: mail dot cmcm at gmail dot com Assigned: nikic (profile)
Status: Closed Package: opcache
PHP Version: 7.3.0 OS: Windows 10
Private report: No CVE-ID: None
 [2018-12-06 20:35 UTC] mail dot cmcm at gmail dot com
Description:
------------
I basically have this code in a project (in a private static function):

$a = false;
$var = "overview";
switch($var)
{
  case "overview":
       $a = true;
       break;

  case "details":
       break;
}
console($a);

And with PHP 7.3 the result is "false"! Doesn't happen with PHP 5.6-7.2.
I tried to reproduce this bug outside my project, but couldn't. However I see nothing in my code that could produce such an odd result. In fact if I add the console output (via ChromePhp) like this
case "overview":
      $a = true;
      console($a);
      break;
I get "true" on both outputs.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-12-06 20:53 UTC] requinix@php.net
-Status: Open +Status: Feedback
 [2018-12-06 20:53 UTC] requinix@php.net
What if you disable opcache?
 [2018-12-07 07:04 UTC] info at cmcm dot info
Indeed, disabling opcache fixed the problem. So is this a bug specific to 7.3 or the windows version? Because I never had a problem with 7.2 and opcache enabled.
 [2018-12-07 07:12 UTC] requinix@php.net
-Status: Feedback +Status: Open -Package: *General Issues +Package: opcache
 [2018-12-07 07:12 UTC] requinix@php.net
I doubt it's specific to Windows. Likely just a regular opcache bug.
 [2018-12-07 11:05 UTC] nikic@php.net
Can you please provide the (non-reduced) source code of the function that is failing? If you can't publish the code, please feel free to mail to me directly at nikic@php.net.
 [2018-12-07 12:17 UTC] mail dot cmcm at gmail dot com
I'm really sorry, but I can't. I'm working on a backend for a music publisher and we're talking about a huge project. When I find the time I'll try again to reproduce the problem outside this project. It doesn't happen if I isolate the method so it could be hard to pinpoint... :(
 [2018-12-07 16:22 UTC] nikic@php.net
For this purpose it's usually enough to only have the function that contains the switch, even if it cannot be run in isolation. The surrounding code (likely) does not matter. The code is only needed to get an opcode dump and see the faulty transformation, a smaller test case can then be reconstructed from there.
 [2018-12-10 15:53 UTC] nikic@php.net
Reduced test case based on code provided via mail:

function test($x) {
    switch ($x["y"]) {
        case "a":
            break;
        case "b":
            break;
    }
}

This generates "Block 4 predecessors missing 1" SSA verification errors, first appearing after jump optimization.
 [2018-12-10 16:53 UTC] nikic@php.net
Okay, that was maybe a bit too reduced. A better variant is:

<?php
function test($x) {
    $a = false;
    switch($x["y"]) {
        case "a":
            $a = true;
            break;
        case "b":
            break;
        case "c":
            break;
    }
    return $a;
}
var_dump(test(["y" => "a"]));

The issue is basically that we currently require that block predecessors are unique. The code for unlinking a block has a broken implementation of the deduplication. However, the more important issue is that if we remove predecessors due to deduplication, we must also adjust phi nodes accordingly.

Those issues can be fixed, but I think that the cleaner fix would be to relax the restriction on duplicate predecessors. Not sure what other fallout that would have though.
 [2019-01-02 08:09 UTC] nikic@php.net
-Assigned To: +Assigned To: nikic
 [2019-01-02 08:33 UTC] nikic@php.net
Automatic comment on behalf of nikita.ppv@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=91888cc372200543d6d40ebb0120d7c8ef7575e3
Log: Fixed bug #77257
 [2019-01-02 08:33 UTC] nikic@php.net
-Status: Assigned +Status: Closed
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Fri Feb 22 09:01:25 2019 UTC