Initialize submatch results to unmatched. They will not be modified for failed alternatives (they might not even be looked at), and would otherwise leave the pair of iterators value-initialized instead of pointing to the end of the searched sequence. Fixes PR22061.
Details
Diff Detail
Event Timeline
The fix looks reasonable, it fixes the OP's problem, and the new test fails w/o the fix.
However, the change to <regex> is in two places, and I don't see how this test exercises both code paths.
Other than that (and the nits in the test) this looks good.
test/std/re/re.results/re.results.acc/index.pass.cpp | ||
---|---|---|
27 | How about assert(m.size() == 6) here? - or >5 since we're checking elements 0..5 | |
50 | Should this be m[5] ? |
Good point, I'll parametrize the test and invoke it for both ECMAScript and extended POSIX.
test/std/re/re.results/re.results.acc/index.pass.cpp | ||
---|---|---|
27 | assert(m.size() == 4) actually, the main match plus three subexpressions. Any out of range access shall return an unmatched result, and the original test was exercising that. | |
50 | Indeed, good catch. |
test/std/re/re.results/re.results.acc/index.pass.cpp | ||
---|---|---|
28 | Ok, then I'm really confused. The code for match_results::operator[] is: return __n < __matches_.size() ? __matches_[__n] : __unmatched_; So how does the change in <regex> affect this result? |
test/std/re/re.results/re.results.acc/index.pass.cpp | ||
---|---|---|
28 | The changes affect unmatched alternative subexpressions. Consider instead the expression "(z)|cd((e)fg)hi", the (z) subexpression would then be m[1] instead of m[3]. In both cases the subscript is within range, so the out-of-range __unmatched_ result is not referenced. |
How about assert(m.size() == 6) here? - or >5 since we're checking elements 0..5