Ticket #164 (closed defect: fixed)

Opened 2 years ago

Last modified 2 years ago

Optimizer drops catch blocks after break or continue in a loop

Reported by: feldgendler Assigned to: hans
Priority: major Milestone:
Component: Optimizer Version: 0.9.4
Keywords: Cc:

Description

Code to reproduce

<?php
try {
    $i = 0;
    while($i++ < 3) {
        try {
            throw new Exception();
            break;
        } catch (Exception $e) {
            exit("PASSED\n");
        }
    }
} catch (Exception $e) {
        exit("FAILED\n");
}
?>

Expected result

PASSED

Actual result

FAILED

Additional info

The bug occurs only if the optimizer is enabled.

Attachments

patch-00upstream-b (1.1 kB) - added by feldgendler on 08/23/06 10:13:41.
Patch to fix the bug

Change History

08/23/06 10:10:33 changed by feldgendler

The reason is that the optimizer replaces opcodes ZEND_BRK and ZEND_CONT with ZEND_JMP at some stage. At one of the later stages, the optimizer sets a control flow path from ZEND_BRK, ZEND_CONT, ZEND_RETURN, and ZEND_EXIT to follow on to the innermost catch block -- this was intended as a measure against needlessly optimizing away catch blocks which follow these opcodes. However, because ZEND_BRK and ZEND_CONT get turned into ZEND_JMP before, this measure fails, and the catch block is dropped.

08/23/06 10:13:41 changed by feldgendler

  • attachment patch-00upstream-b added.

Patch to fix the bug

08/23/06 10:14:45 changed by feldgendler

Please apply the attached patch.

My fix marks ZEND_BRK and ZEND_CONT instructions with extended_value when replacing them with ZEND_JMP. At the following stage, this mark is used to detect a former ZEND_BRK and ZEND_CONT and applying the necessary logic to them.

Sorry for the weird name of the attached file -- this was unintentional.

08/23/06 16:46:43 changed by hans

  • status changed from new to closed.
  • resolution set to fixed.

I have just applied your patch to the repository. Thanks very much for your input!