[libcxx-commits] [libcxx] r357190 - Fix PR#35967: '<regex> syntax_option_type is not a proper bitmask' Sadly, this is an ABI break, so it's only available if you define either '_LIBCPP_ABI_VERSION > 2' or '_LIBCPP_ABI_UNSTABLE' or '_LIBCPP_ABI_REGEX_CONSTANTS_NONZERO' and rebuild your dylib.

Marshall Clow via libcxx-commits libcxx-commits at lists.llvm.org
Thu Mar 28 10:30:24 PDT 2019


Author: marshall
Date: Thu Mar 28 10:30:23 2019
New Revision: 357190

URL: http://llvm.org/viewvc/llvm-project?rev=357190&view=rev
Log:
Fix PR#35967: '<regex> syntax_option_type is not a proper bitmask' Sadly, this is an ABI break, so it's only available if you define either '_LIBCPP_ABI_VERSION > 2' or '_LIBCPP_ABI_UNSTABLE' or '_LIBCPP_ABI_REGEX_CONSTANTS_NONZERO' and rebuild your dylib.

Modified:
    libcxx/trunk/include/__config
    libcxx/trunk/include/regex
    libcxx/trunk/test/std/re/re.const/re.synopt/syntax_option_type.pass.cpp
    libcxx/trunk/test/std/re/re.regex/re.regex.construct/default.pass.cpp

Modified: libcxx/trunk/include/__config
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=357190&r1=357189&r2=357190&view=diff
==============================================================================
--- libcxx/trunk/include/__config (original)
+++ libcxx/trunk/include/__config Thu Mar 28 10:30:23 2019
@@ -100,6 +100,8 @@
 #  define _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
 // Unstable attempt to provide a more optimized std::function
 #  define _LIBCPP_ABI_OPTIMIZED_FUNCTION
+// All the regex constants must be distinct and nonzero.
+#  define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
 #elif _LIBCPP_ABI_VERSION == 1
 #  if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
 // Enable compiling copies of now inline methods into the dylib to support

Modified: libcxx/trunk/include/regex
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/regex?rev=357190&r1=357189&r2=357190&view=diff
==============================================================================
--- libcxx/trunk/include/regex (original)
+++ libcxx/trunk/include/regex Thu Mar 28 10:30:23 2019
@@ -793,7 +793,11 @@ enum syntax_option_type
     nosubs     = 1 << 1,
     optimize   = 1 << 2,
     collate    = 1 << 3,
+#ifdef _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
+    ECMAScript = 1 << 9,
+#else
     ECMAScript = 0,
+#endif
     basic      = 1 << 4,
     extended   = 1 << 5,
     awk        = 1 << 6,
@@ -801,6 +805,16 @@ enum syntax_option_type
     egrep      = 1 << 8
 };
 
+inline _LIBCPP_CONSTEXPR
+syntax_option_type __get_grammar(syntax_option_type __g)
+{
+#ifdef _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
+    return static_cast<syntax_option_type>(__g & 0x3F0);
+#else
+    return static_cast<syntax_option_type>(__g & 0x1F0);
+#endif
+}
+
 inline _LIBCPP_INLINE_VISIBILITY
 _LIBCPP_CONSTEXPR
 syntax_option_type
@@ -2526,19 +2540,27 @@ public:
     // construct/copy/destroy:
     _LIBCPP_INLINE_VISIBILITY
     basic_regex()
-        : __flags_(), __marked_count_(0), __loop_count_(0), __open_count_(0),
+        : __flags_(regex_constants::ECMAScript), __marked_count_(0), __loop_count_(0), __open_count_(0),
           __end_(0)
         {}
     _LIBCPP_INLINE_VISIBILITY
     explicit basic_regex(const value_type* __p, flag_type __f = regex_constants::ECMAScript)
         : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
           __end_(0)
-        {__parse(__p, __p + __traits_.length(__p));}
+        {
+        if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
+        __parse(__p, __p + __traits_.length(__p));
+        }
+
     _LIBCPP_INLINE_VISIBILITY
     basic_regex(const value_type* __p, size_t __len, flag_type __f = regex_constants::ECMAScript)
         : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
           __end_(0)
-        {__parse(__p, __p + __len);}
+        {
+        if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
+        __parse(__p, __p + __len);
+        }
+
 //     basic_regex(const basic_regex&) = default;
 //     basic_regex(basic_regex&&) = default;
     template <class _ST, class _SA>
@@ -2547,21 +2569,31 @@ public:
                              flag_type __f = regex_constants::ECMAScript)
         : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
           __end_(0)
-        {__parse(__p.begin(), __p.end());}
+        {
+        if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
+        __parse(__p.begin(), __p.end());
+        }
+
     template <class _ForwardIterator>
         _LIBCPP_INLINE_VISIBILITY
         basic_regex(_ForwardIterator __first, _ForwardIterator __last,
                     flag_type __f = regex_constants::ECMAScript)
         : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
           __end_(0)
-        {__parse(__first, __last);}
+        {
+        if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
+        __parse(__first, __last);
+        }
 #ifndef _LIBCPP_CXX03_LANG
     _LIBCPP_INLINE_VISIBILITY
     basic_regex(initializer_list<value_type> __il,
                 flag_type __f = regex_constants::ECMAScript)
         : __flags_(__f), __marked_count_(0), __loop_count_(0), __open_count_(0),
           __end_(0)
-        {__parse(__il.begin(), __il.end());}
+        {
+        if (__get_grammar(__flags_) == 0) __flags_ |= regex_constants::ECMAScript;
+        __parse(__il.begin(), __il.end());
+        }
 #endif  // _LIBCPP_CXX03_LANG
 
 //    ~basic_regex() = default;
@@ -3043,7 +3075,7 @@ basic_regex<_CharT, _Traits>::__parse(_F
         __h.release();
         __end_ = __start_.get();
     }
-    switch (__flags_ & 0x1F0)
+    switch (__get_grammar(__flags_))
     {
     case ECMAScript:
         __first = __parse_ecma_exp(__first, __last);
@@ -3512,7 +3544,7 @@ basic_regex<_CharT, _Traits>::__parse_QU
                     __first = ++__temp;
                     break;
                 default:
-                    if ((__flags_ & 0x1F0) == awk)
+                    if (__get_grammar(__flags_) == awk)
                         __first = __parse_awk_escape(++__first, __last);
                     break;
                 }
@@ -3596,7 +3628,7 @@ basic_regex<_CharT, _Traits>::__parse_ER
 {
     if (__first != __last)
     {
-        unsigned __grammar = __flags_ & 0x1F0;
+        unsigned __grammar = __get_grammar(__flags_);
         switch (*__first)
         {
         case '*':
@@ -3717,7 +3749,7 @@ basic_regex<_CharT, _Traits>::__parse_br
         // __ml owned by *this
         if (__first == __last)
             __throw_regex_error<regex_constants::error_brack>();
-        if ((__flags_ & 0x1F0) != ECMAScript && *__first == ']')
+        if (__get_grammar(__flags_) != ECMAScript && *__first == ']')
         {
             __ml->__add_char(']');
             ++__first;
@@ -3778,7 +3810,7 @@ basic_regex<_CharT, _Traits>::__parse_ex
             else if (*__temp == '.')
                 __first = __parse_collating_symbol(++__temp, __last, __start_range);
         }
-        unsigned __grammar = __flags_ & 0x1F0;
+        unsigned __grammar = __get_grammar(__flags_);
         if (__start_range.empty())
         {
             if ((__grammar == ECMAScript || __grammar == awk) && *__first == '\\')
@@ -5848,7 +5880,7 @@ basic_regex<_CharT, _Traits>::__match_at
         match_results<const _CharT*, _Allocator>& __m,
         regex_constants::match_flag_type __flags, bool __at_first) const
 {
-    if ((__flags_ & 0x1F0) == ECMAScript)
+    if (__get_grammar(__flags_) == ECMAScript)
         return __match_at_start_ecma(__first, __last, __m, __flags, __at_first);
     if (mark_count() == 0)
         return __match_at_start_posix_nosubs(__first, __last, __m, __flags, __at_first);

Modified: libcxx/trunk/test/std/re/re.const/re.synopt/syntax_option_type.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/re/re.const/re.synopt/syntax_option_type.pass.cpp?rev=357190&r1=357189&r2=357190&view=diff
==============================================================================
--- libcxx/trunk/test/std/re/re.const/re.synopt/syntax_option_type.pass.cpp (original)
+++ libcxx/trunk/test/std/re/re.const/re.synopt/syntax_option_type.pass.cpp Thu Mar 28 10:30:23 2019
@@ -38,7 +38,11 @@ int main(int, char**)
     assert(std::regex_constants::nosubs != 0);
     assert(std::regex_constants::optimize != 0);
     assert(std::regex_constants::collate != 0);
+#ifdef _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO  // https://bugs.llvm.org/show_bug.cgi?id=35967
+    assert(std::regex_constants::ECMAScript != 0);
+#else
     assert(std::regex_constants::ECMAScript == 0);
+#endif
     assert(std::regex_constants::basic != 0);
     assert(std::regex_constants::extended != 0);
     assert(std::regex_constants::awk != 0);

Modified: libcxx/trunk/test/std/re/re.regex/re.regex.construct/default.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/re/re.regex/re.regex.construct/default.pass.cpp?rev=357190&r1=357189&r2=357190&view=diff
==============================================================================
--- libcxx/trunk/test/std/re/re.regex/re.regex.construct/default.pass.cpp (original)
+++ libcxx/trunk/test/std/re/re.regex/re.regex.construct/default.pass.cpp Thu Mar 28 10:30:23 2019
@@ -21,7 +21,7 @@ void
 test()
 {
     std::basic_regex<CharT> r;
-    assert(r.flags() == 0);
+    assert(r.flags() == std::regex_constants::ECMAScript);
     assert(r.mark_count() == 0);
 }
 




More information about the libcxx-commits mailing list