Bug #76046 [NEW]: PHP generates "FE_FREE" opcode on the wrong line.

From: Date: Sat, 03 Mar 2018 11:58:24 +0000
Subject: Bug #76046 [NEW]: PHP generates "FE_FREE" opcode on the wrong line.
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-214191@lists.php.net to get a copy of this message
From:             derick@php.net
Operating system: *
PHP version:      7.2.3
Package:          Scripting Engine problem
Bug Type:         Bug
Bug description:PHP generates "FE_FREE" opcode on the wrong line.

Description:
------------
This was originally filed as
https://github.com/sebastianbergmann/php-code-coverage/issues/589
 and
https://bugs.xdebug.org/view.php?id=1530 .

With the script:

  1 <?php
  2 foreach (['a'] as $item) {
  3     if (false) {
  4         echo "Test\n";
  5         echo "Test\n";
  6     }
  7 }
  8 ?>

I found that PHP generates the following opcodes (without opcache
enabled):

filename:       /home/derick/dev/php/derickr-xdebug/tests/bug01530.inc
function name:  (null)
number of ops:  12
compiled vars:  !0 = $item
line     #* E I O op                           fetch          ext 
return  operands
-------------------------------------------------------------------------------------
   2     0  E >   EXT_STMT                                              
  
         1      > FE_RESET_R                                       $1   
  <array>, ->10
         2    > > FE_FETCH_R                                            
  $1, !0, ->10
   3     3    >   EXT_STMT                                              
  
         4      > JMPZ                                                  
  <false>, ->9
   4     5    >   EXT_STMT                                              
  
         6        ECHO                                                  
  'Test%0A'
   5     7        EXT_STMT                                              
  
         8        ECHO                                                  
  'Test%0A'
         9    > > JMP                                                   
  ->2
        10    >   FE_FREE                                               
  $1
   9    11      > RETURN                                                
  1

The foreach keyword is represented by opcode 1 and 2 (FE_RESET_R and
FE_FETCH_R), and you see that they can both jump to opcode 10 (->10). It
would do that if the loop is empty (FE_RESET_R) or exhausted
(FE_FETCH_R). PHP has generated opcode 10 (FE_FREE) on line 5. Which is
really not correct, as it should put it on line 7. It does this wrong
for both PHP 7.0, 7.1 and 7.2.


Test script:
---------------
 <?php
 foreach (['a'] as $item) {
     if (false) {
         echo "Test\n";
         echo "Test\n";
     }
 }
 ?>

Expected result:
----------------
   5     7        EXT_STMT                                              
  
         8        ECHO                                                  
  'Test%0A'
         9    > > JMP                                                   
  ->2
   7    10    >   FE_FREE                                               
  $1
   9    11      > RETURN                                                
  1

Actual result:
--------------
   5     7        EXT_STMT                                              
  
         8        ECHO                                                  
  'Test%0A'
         9    > > JMP                                                   
  ->2
        10    >   FE_FREE                                               
  $1
   9    11      > RETURN                                                
  1

-- 
Edit bug report at https://bugs.php.net/bug.php?id=76046&edit=1
-- 
Try a snapshot (PHP 5.4):   https://bugs.php.net/fix.php?id=76046&r=trysnapshot54
Try a snapshot (PHP 5.5):   https://bugs.php.net/fix.php?id=76046&r=trysnapshot55
Try a snapshot (trunk):     https://bugs.php.net/fix.php?id=76046&r=trysnapshottrunk
Fixed in SVN:               https://bugs.php.net/fix.php?id=76046&r=fixed
Fixed in release:           https://bugs.php.net/fix.php?id=76046&r=alreadyfixed
Need backtrace:             https://bugs.php.net/fix.php?id=76046&r=needtrace
Need Reproduce Script:      https://bugs.php.net/fix.php?id=76046&r=needscript
Try newer version:          https://bugs.php.net/fix.php?id=76046&r=oldversion
Not developer issue:        https://bugs.php.net/fix.php?id=76046&r=support
Expected behavior:          https://bugs.php.net/fix.php?id=76046&r=notwrong
Not enough info:            https://bugs.php.net/fix.php?id=76046&r=notenoughinfo
Submitted twice:            https://bugs.php.net/fix.php?id=76046&r=submittedtwice
register_globals:           https://bugs.php.net/fix.php?id=76046&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=76046&r=php4
Daylight Savings:           https://bugs.php.net/fix.php?id=76046&r=dst
IIS Stability:              https://bugs.php.net/fix.php?id=76046&r=isapi
Install GNU Sed:            https://bugs.php.net/fix.php?id=76046&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=76046&r=float
No Zend Extensions:         https://bugs.php.net/fix.php?id=76046&r=nozend
MySQL Configuration Error:  https://bugs.php.net/fix.php?id=76046&r=mysqlcfg



Thread (4 messages)

« previous php.bugs (#214191) next »