[libcxx-commits] [libcxx] d83a3ea - [libc++] Fix std::regex_search to match $ alone with match_default flag (#78845)

via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jan 22 11:15:10 PST 2024


Author: Sanjay Marreddi
Date: 2024-01-22T14:15:05-05:00
New Revision: d83a3ea529575f17ea6ea608a43bca0b3065dcfe

URL: https://github.com/llvm/llvm-project/commit/d83a3ea529575f17ea6ea608a43bca0b3065dcfe
DIFF: https://github.com/llvm/llvm-project/commit/d83a3ea529575f17ea6ea608a43bca0b3065dcfe.diff

LOG: [libc++] Fix std::regex_search to match $ alone with match_default flag (#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 #75042

Added: 
    

Modified: 
    libcxx/include/regex
    libcxx/test/std/re/re.const/re.matchflag/match_not_eol.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/regex b/libcxx/include/regex
index b575a267583b5fe..48af5b8b57fd649 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -5124,6 +5124,14 @@ bool basic_regex<_CharT, _Traits>::__search(
       }
       __m.__matches_.assign(__m.size(), __m.__unmatched_);
     }
+    __m.__matches_.assign(__m.size(), __m.__unmatched_);
+    if (__match_at_start(__first, __last, __m, __flags, false)) {
+      __m.__prefix_.second  = __m[0].first;
+      __m.__prefix_.matched = __m.__prefix_.first != __m.__prefix_.second;
+      __m.__suffix_.first   = __m[0].second;
+      __m.__suffix_.matched = __m.__suffix_.first != __m.__suffix_.second;
+      return true;
+    }
   }
   __m.__matches_.clear();
   return false;

diff  --git a/libcxx/test/std/re/re.const/re.matchflag/match_not_eol.pass.cpp b/libcxx/test/std/re/re.const/re.matchflag/match_not_eol.pass.cpp
index edeea517d2537a3..89d939eaf809f4b 100644
--- a/libcxx/test/std/re/re.const/re.matchflag/match_not_eol.pass.cpp
+++ b/libcxx/test/std/re/re.const/re.matchflag/match_not_eol.pass.cpp
@@ -47,5 +47,44 @@ int main(int, char**)
     assert( std::regex_search(target, re, std::regex_constants::match_not_eol));
     }
 
+    {
+      std::string target = "foo";
+      std::regex re("$");
+      assert(std::regex_search(target, re));
+      assert(!std::regex_search(target, re, std::regex_constants::match_not_eol));
+
+      std::smatch match;
+      assert(std::regex_search(target, match, re));
+      assert(match.position(0) == 3);
+      assert(match.length(0) == 0);
+      assert(!std::regex_search(target, match, re, std::regex_constants::match_not_eol));
+      assert(match.length(0) == 0);
+    }
+
+    {
+      std::string target = "foo";
+      std::regex re("$", std::regex::multiline);
+      std::smatch match;
+      assert(std::regex_search(target, match, re));
+      assert(match.position(0) == 3);
+      assert(match.length(0) == 0);
+      assert(!std::regex_search(target, match, re, std::regex_constants::match_not_eol));
+      assert(match.length(0) == 0);
+    }
+
+    {
+      std::string target = "foo";
+      std::regex re("$");
+      assert(!std::regex_match(target, re));
+      assert(!std::regex_match(target, re, std::regex_constants::match_not_eol));
+    }
+
+    {
+      std::string target = "a";
+      std::regex re("^b*$");
+      assert(!std::regex_search(target, re));
+      assert(!std::regex_search(target, re, std::regex_constants::match_not_eol));
+    }
+
   return 0;
 }


        


More information about the libcxx-commits mailing list