Index: libcxx/include/regex =================================================================== --- libcxx/include/regex +++ libcxx/include/regex @@ -1745,8 +1745,6 @@ void __back_ref<_CharT>::__exec(__state& __s) const { - if (__mexp_ > __s.__sub_matches_.size()) - __throw_regex_error(); sub_match& __sm = __s.__sub_matches_[__mexp_-1]; if (__sm.matched) { @@ -4320,8 +4318,6 @@ for (++__first; __first != __last && '0' <= *__first && *__first <= '9'; ++__first) __v = 10 * __v + *__first - '0'; - if (__v > mark_count()) - __throw_regex_error(); __push_back_ref(__v); } } @@ -4712,6 +4708,9 @@ void basic_regex<_CharT, _Traits>::__push_back_ref(int __i) { + if (__i > static_cast(mark_count())) + __throw_regex_error(); + if (flags() & icase) __end_->first() = new __back_ref_icase<_CharT, _Traits> (__traits_, __i, __end_->first()); Index: libcxx/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp =================================================================== --- libcxx/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp +++ libcxx/test/std/re/re.regex/re.regex.construct/bad_backref.pass.cpp @@ -19,11 +19,14 @@ #include #include "test_macros.h" -static bool error_badbackref_thrown(const char *pat) +static bool error_badbackref_thrown( + const char *pat, + std::regex_constants::syntax_option_type flags = + std::regex_constants::ECMAScript) { bool result = false; try { - std::regex re(pat); + std::regex re(pat, flags); } catch (const std::regex_error &ex) { result = (ex.code() == std::regex_constants::error_backref); } @@ -34,6 +37,7 @@ { assert(error_badbackref_thrown("\\1abc")); // no references assert(error_badbackref_thrown("ab(c)\\2def")); // only one reference + assert(error_badbackref_thrown("(cat)\\1", std::regex_constants::basic)); // this should NOT throw, because we only should look at the '1' // See https://bugs.llvm.org/show_bug.cgi?id=31387