Ticket #164 (closed defect: fixed)
Optimizer drops catch blocks after break or continue in a loop
| Reported by: | feldgendler | Owned by: | 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
Change History
comment:2 Changed 4 years ago 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.
comment:3 Changed 4 years ago 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!
comment:4 Changed 12 months ago by getagoodbuy
comment:6 Changed 6 months ago by sim
decoration Changed 1 year ago by admin
bathtub Changed 1 year ago by admin
solar system Changed 1 year ago by admin
stair parts Changed 1 year ago by admin
solar supply Changed 1 year ago by admin

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.