diff options
author | Nicholas Clark <nick@ccl4.org> | 2012-04-16 07:51:49 +0200 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2012-06-19 10:19:28 +0200 |
commit | cdc1aa425ff891f079f6e8b0787d0d9aa145bd47 (patch) | |
tree | 05dbab134a6a6984aa7606cf3753e4368e9462d3 /pp_hot.c | |
parent | 66d2c7cb575fb77aa0403c44521daff3e400f738 (diff) | |
download | perl-cdc1aa425ff891f079f6e8b0787d0d9aa145bd47.tar.gz |
In pp_iter, handle end of range at IV_MAX without undefined behaviour.
The previous code assumed that incrementing a signed integer value wraps.
We're lucky that it has (so far), as it's undefined behaviour in C.
So refactor to code which doesn't assume anything.
Diffstat (limited to 'pp_hot.c')
-rw-r--r-- | pp_hot.c | 16 |
1 files changed, 7 insertions, 9 deletions
@@ -1897,7 +1897,7 @@ PP(pp_iter) /* don't risk potential race */ if (SvREFCNT(*itersvp) == 1 && !SvMAGICAL(*itersvp)) { /* safe to reuse old SV */ - sv_setiv(*itersvp, cx->blk_loop.state_u.lazyiv.cur++); + sv_setiv(*itersvp, cx->blk_loop.state_u.lazyiv.cur); } else { @@ -1905,17 +1905,15 @@ PP(pp_iter) * completely new SV for closures/references to work as they * used to */ oldsv = *itersvp; - *itersvp = newSViv(cx->blk_loop.state_u.lazyiv.cur++); + *itersvp = newSViv(cx->blk_loop.state_u.lazyiv.cur); SvREFCNT_dec(oldsv); } - /* Handle end of range at IV_MAX */ - if ((cx->blk_loop.state_u.lazyiv.cur == IV_MIN) && - (cx->blk_loop.state_u.lazyiv.end == IV_MAX)) - { - cx->blk_loop.state_u.lazyiv.cur++; - cx->blk_loop.state_u.lazyiv.end++; - } + if (cx->blk_loop.state_u.lazyiv.cur == IV_MAX) { + /* Handle end of range at IV_MAX */ + cx->blk_loop.state_u.lazyiv.end = IV_MIN; + } else + ++cx->blk_loop.state_u.lazyiv.cur; RETPUSHYES; } |