|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2020-10-18 19:23 UTC] rixafy at gmail dot com
Description: ------------ I didn't manage to isolate the bug from that package, I provided also html stacktrace in repository and description in readme. It seems like some condition is behaving differently when opcache is enabled, condition passed, but there is no way this condition would even be executed, because condition above (same condition - strlen($newIndent) > strlen($indent)) cannot pass. Test script: --------------- https://github.com/Rixafy/php8.0.0-rc1-opcache-bug PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Oct 27 03:00:02 2025 UTC |
To ease with the debugging I have reduced the example to the following: ================= <?php echo '<pre>'; $tokens = [ 5 => ':', 6 => 'bar', 7 => ' ', ]; for ($pos = 5; $pos < 8; $pos++) { $t = $tokens[$pos]; if ($t === ':') { // KeyValuePair separator echo 'Sep: ' . $pos . PHP_EOL; $hasKey = true; } elseif ($t[0] === " ") { // Indent echo 'Indent: ' . $pos . PHP_EOL; if ($hasValue && !$hasKey) { } elseif ($hasKey) { $hasKey = $hasValue = false; } } else { // Value echo 'Val: ' . $pos . PHP_EOL; $hasValue = true; } } echo 'Return: ' . $pos . PHP_EOL; ===================== Expected: Sep: 5 Val: 6 Indent: 7 Return: 8 ==================== With OPCache enabled this will go into infinite loop. I have also made a slightly different test case https://pastebin.com/sCbzpQ5D This one repeats loop no. 7 twiceI have arrived at a similar reduction: <?php function test($a, $b, $c) { do { if ($a && !$b) { break; } else if ($b) { echo "foo\n"; } echo "bar\n"; } while ($c); echo "baz\n"; } test(true, true, false);Seems to be introduced by the block pass: test: ; (lines=15, args=3, vars=3, tmps=2) ; (before block pass) ; /home/nikic/php/php-8.0/t007.php:3-13 ; return [] RANGE[0..0] BB0: ; start lines=[0-2] ; to=(BB1) 0000 CV0($a) = RECV 1 0001 CV1($b) = RECV 2 0002 CV2($c) = RECV 3 BB1: ; follow target lines=[3-3] ; to=(BB5, BB2) 0003 T3 = JMPZ_EX CV0($a) BB5 BB2: ; follow lines=[4-6] ; to=(BB5, BB8) 0004 T4 = BOOL_NOT CV1($b) 0005 T3 = BOOL T4 0006 JMPZNZ T3 BB5 BB8 BB3: ; unreachable lines=[7-7] ; to=(BB8) 0007 JMP BB8 BB4: ; unreachable lines=[8-8] ; to=(BB7) 0008 JMP BB7 BB5: ; target lines=[9-9] ; to=(BB7, BB6) 0009 JMPZ CV1($b) BB7 BB6: ; follow lines=[10-10] ; to=(BB7) 0010 ECHO string("foo ") BB7: ; follow target lines=[11-12] ; to=(BB1, BB8) 0011 ECHO string("bar ") 0012 JMPNZ CV2($c) BB1 BB8: ; follow target exit lines=[13-14] 0013 ECHO string("baz ") 0014 RETURN null test: ; (lines=11, args=3, vars=3, tmps=2) ; (after block pass) ; /home/nikic/php/php-8.0/t007.php:3-13 ; return [] RANGE[0..0] BB0: ; start target lines=[0-2] ; to=(BB1) 0000 CV0($a) = RECV 1 0001 CV1($b) = RECV 2 0002 CV2($c) = RECV 3 BB1: ; follow target lines=[3-3] ; to=(BB5, BB2) 0003 JMPZ CV0($a) BB5 BB2: ; follow lines=[4-4] ; to=(BB8, BB0) 0004 JMPZNZ CV1($b) BB8 BB0 BB5: ; target lines=[5-5] ; to=(BB7, BB6) 0005 JMPZ CV1($b) BB7 BB6: ; follow lines=[6-6] ; to=(BB7) 0006 ECHO string("foo ") BB7: ; follow target lines=[7-8] ; to=(BB1, BB8) 0007 ECHO string("bar ") 0008 JMPNZ CV2($c) BB1 BB8: ; follow target exit lines=[9-10] 0009 ECHO string("baz ") 0010 RETURN null