Skip to content

Commit d83a3ea

Browse files
[libc++] Fix std::regex_search to match $ alone with match_default flag (llvm#78845)
Using std::regex_search with the regex_constant match_default and a simple regex pattern `$` is expected to match general strings such as _"a", "ab", "abc"..._ at `[last, last)` positions. But, the current implementation fails to do so. Fixes llvm#75042
1 parent 6d5f8d3 commit d83a3ea

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

libcxx/include/regex

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5124,6 +5124,14 @@ bool basic_regex<_CharT, _Traits>::__search(
51245124
}
51255125
__m.__matches_.assign(__m.size(), __m.__unmatched_);
51265126
}
5127+
__m.__matches_.assign(__m.size(), __m.__unmatched_);
5128+
if (__match_at_start(__first, __last, __m, __flags, false)) {
5129+
__m.__prefix_.second = __m[0].first;
5130+
__m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
5131+
__m.__suffix_.first = __m[0].second;
5132+
__m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;
5133+
return true;
5134+
}
51275135
}
51285136
__m.__matches_.clear();
51295137
return false;

libcxx/test/std/re/re.const/re.matchflag/match_not_eol.pass.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,44 @@ int main(int, char**)
4747
assert( std::regex_search(target, re, std::regex_constants::match_not_eol));
4848
}
4949

50+
{
51+
std::string target = "foo";
52+
std::regex re("$");
53+
assert(std::regex_search(target, re));
54+
assert(!std::regex_search(target, re, std::regex_constants::match_not_eol));
55+
56+
std::smatch match;
57+
assert(std::regex_search(target, match, re));
58+
assert(match.position(0) == 3);
59+
assert(match.length(0) == 0);
60+
assert(!std::regex_search(target, match, re, std::regex_constants::match_not_eol));
61+
assert(match.length(0) == 0);
62+
}
63+
64+
{
65+
std::string target = "foo";
66+
std::regex re("$", std::regex::multiline);
67+
std::smatch match;
68+
assert(std::regex_search(target, match, re));
69+
assert(match.position(0) == 3);
70+
assert(match.length(0) == 0);
71+
assert(!std::regex_search(target, match, re, std::regex_constants::match_not_eol));
72+
assert(match.length(0) == 0);
73+
}
74+
75+
{
76+
std::string target = "foo";
77+
std::regex re("$");
78+
assert(!std::regex_match(target, re));
79+
assert(!std::regex_match(target, re, std::regex_constants::match_not_eol));
80+
}
81+
82+
{
83+
std::string target = "a";
84+
std::regex re("^b*$");
85+
assert(!std::regex_search(target, re));
86+
assert(!std::regex_search(target, re, std::regex_constants::match_not_eol));
87+
}
88+
5089
return 0;
5190
}

0 commit comments

Comments
 (0)