[PATCH] D37955: [libcxx] Fix invert negative bracket match.

Tim Shen via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sat Sep 16 22:05:24 PDT 2017


timshen created this revision.
Herald added a subscriber: sanjoy.
Herald added a reviewer: EricWF.

Ideally we want !(neg_mask || neg_char), aka (!neg_mask && !neg_char). Before the change, the code is (!neg_mask || !neg_char).

This fixes PR34310.


https://reviews.llvm.org/D37955

Files:
  libcxx/include/regex
  libcxx/test/std/re/re.alg/re.alg.search/invert_neg_word_search.pass.cpp


Index: libcxx/test/std/re/re.alg/re.alg.search/invert_neg_word_search.pass.cpp
===================================================================
--- /dev/null
+++ libcxx/test/std/re/re.alg/re.alg.search/invert_neg_word_search.pass.cpp
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <regex>
+
+// template <class BidirectionalIterator, class Allocator, class charT, class traits>
+//     bool
+//     regex_search(BidirectionalIterator first, BidirectionalIterator last,
+//                  match_results<BidirectionalIterator, Allocator>& m,
+//                  const basic_regex<charT, traits>& e,
+//                  regex_constants::match_flag_type flags = regex_constants::match_default);
+
+#include <iostream>
+#include <regex>
+#include <cassert>
+#include "test_macros.h"
+
+// PR34310
+int main()
+{
+  assert(std::regex_search("HelloWorld", std::regex("[^\\W]")));
+  assert(std::regex_search("_", std::regex("[^\\W]")));
+  return 0;
+}
Index: libcxx/include/regex
===================================================================
--- libcxx/include/regex
+++ libcxx/include/regex
@@ -2409,17 +2409,23 @@
                 goto __exit;
             }
         }
-        if (!__neg_chars_.empty())
+        // set of "__found" chars =
+        //   union(complement(union(__neg_chars_, __neg_mask_)),
+        //         other cases...)
+        // __neg_chars_ and __neg_mask_'d better be handled together, as there
+        // are no short circuit opportunities.
         {
-            for (size_t __i = 0; __i < __neg_chars_.size(); ++__i)
-            {
-                if (__ch == __neg_chars_[__i])
-                    goto __is_neg_char;
-            }
+          const bool __in_neg_mask = __neg_mask_ &&
+              __traits_.isctype(__ch, __neg_mask_);
+          const bool __in_neg_chars =
+              std::find(__neg_chars_.begin(), __neg_chars_.end(), __ch) !=
+              __neg_chars_.end();
+          if (!(__in_neg_mask || __in_neg_chars))
+          {
             __found = true;
             goto __exit;
+          }
         }
-__is_neg_char:
         if (!__ranges_.empty())
         {
             string_type __s2 = __collate_ ?
@@ -2451,11 +2457,6 @@
             __found = true;
             goto __exit;
         }
-        if (__neg_mask_ && !__traits_.isctype(__ch, __neg_mask_))
-        {
-            __found = true;
-            goto __exit;
-        }
     }
     else
         __found = __negate_;  // force reject


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D37955.115553.patch
Type: text/x-patch
Size: 2821 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170917/e2d42f68/attachment.bin>


More information about the cfe-commits mailing list