View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001509 | Xdebug | Code Coverage | public | 2018-01-03 12:56 | 2018-01-22 18:21 |
Reporter | emir | Assigned To | derick | ||
Priority | normal | Severity | major | Reproducibility | always |
Status | closed | Resolution | fixed | ||
OS | MacOS | OS Version | 10.13.2 | ||
Product Version | 2.6.0beta1 | ||||
Fixed in Version | 2.6.0rc1 | ||||
Summary | 0001509: Code coverage missing for case inside switch with PHP 7.2 | ||||
Description | Code coverage is not attributed for case statements. This was fixed in https://github.com/xdebug/xdebug/commit/040ec0218d9f07b1d6d0b20dbad0c156e578e6e8 and released in 2.6.0alpha1 but with 2.6.0beta1 it is still not working. | ||||
Steps To Reproduce | Test: class DummyTest extends \PHPUnit\Framework\TestCase
} class TestClass | ||||
Additional Information | php -vPHP 7.2.0 (cli) (built: Dec 3 2017 21:46:44) ( NTS ) | ||||
Tags | No tags attached. | ||||
Operating System | |||||
PHP Version | 7.2.0-7.2.4 | ||||
|
Hmm, I don't quite know what to do with this. technically, this is a "work as designed", as the case statements are never hit, yet they can still be. But I can see why it is confusing. Look at the VLD dump: {nowiki}4 0 E > EXT_NOP There are 4 possible outcomes for the "switch", jump to 8, 10, 12, or 4. Because you feed it three strings ("foo", "bar", and "1"), the last case (jump to 4), won't be reached. Yet, it is possible that it can be. For example, if you feed a 3.14 as argument to the switch. In that case, all the case statements (on line 7 and 10, opcodes 4-7) are correctly covered. But I can understand that logically, this can almost never happen. I don't see a way around this though as ignoring all the case/jmpnz cases isn't proper either and you might get a wrong sense of coverage. If you have an idea, I'd be happy to hear it. |
|
I am not sure you understood me. This is a clear regression compared to Xdebug 2.5.5 on PHP 7.1.12. There this class gets 100% coverage and the case statements are hit and attributed correctly. |
|
In PHP 7.2 no case statements are attributed. I have tested this using php-code-coverage 5.3.0 with PHPUnit 6.2.4. |
|
Here is a shortest way to reproduce it, you can compare 7.1 with Xdebug 2.5.5 vs 7.2 with latest Xdebug dev: https://travis-ci.org/emirb/phpunit-xdebug-coverage-cases |
|
I understood you perfectly, and I can reproduce it too, but it isn't wrong as the case statements itself are never actually hit. They're shortcutted by the switch jump table optimisation, see: https://derickrethans.nl/php7.2-switch.html In order for the case statements to be covered, you need to feed switch a value that doesn't trigger the jump table optimisation, by giving it a wrong type. If you do that, the case statements are covered. Xdebug can't know which case statements belong to the entries in the jump table. I also can't simply mark all case statements as "can't reach either", because in some cases they can be. |
|
I understand, I am aware of switch jump table optimisation but I assumed that its addition will still keep the behaviour the same as it was. The optimisation should benefit the performance only, right? My assumption (and I guess by majority of other people doing the upgrade )is that the upgrade to 7.2 should not decrease the coverage. |
|
I agree that an upgrade to 7.2 shouldn't decrease it, but it unfortunately does. I can not easily see which specific cases were executed, as they are not stored together in the oparray as should be evident from my first comment. For example, the statements belonging to "case 'foo'" are done in op codes 8-9, which are not close to either the jump table (op 3), or the case+jump (op 4 and 5). From seeing code executed in op 8-9, I don't know why that was. Perhaps it is possible to see which jump was taken in the switch_string, find out which other op codes jump to that line (op 5, potentially), and then scan backwards to the case statement (op 4), but I do not know how reliable this would be. Perhaps Nikita has an idea (I'll email him). cheers, |
|
Cheers, merged into Git master now. |
Date Modified | Username | Field | Change |
---|---|---|---|
2018-01-03 12:56 | emir | New Issue | |
2018-01-03 20:14 | derick | Note Added: 0004541 | |
2018-01-03 20:14 | derick | Status | new => resolved |
2018-01-03 20:14 | derick | Resolution | open => not fixable |
2018-01-03 20:14 | derick | Assigned To | => derick |
2018-01-03 20:25 | emir | Note Added: 0004542 | |
2018-01-03 20:25 | emir | Status | resolved => new |
2018-01-03 20:25 | emir | Resolution | not fixable => reopened |
2018-01-03 20:26 | emir | Note Added: 0004543 | |
2018-01-03 21:07 | emir | Note Added: 0004544 | |
2018-01-03 21:34 | derick | Note Added: 0004545 | |
2018-01-03 21:41 | emir | Note Added: 0004546 | |
2018-01-04 16:17 | derick | Note Added: 0004547 | |
2018-01-04 16:18 | derick | Note Edited: 0004541 | |
2018-01-04 16:18 | derick | Note Edited: 0004541 | |
2018-01-04 16:19 | derick | Note Edited: 0004541 | |
2018-01-05 23:59 | derick | Note Added: 0004549 | |
2018-01-05 23:59 | derick | Status | new => closed |
2018-01-05 23:59 | derick | Resolution | reopened => fixed |
2018-01-05 23:59 | derick | Fixed in Version | => 2.6.0 |
2018-01-22 18:21 | derick | Fixed in Version | 2.6.0 => 2.6.0rc1 |