@@ -1710,7 +1710,7 @@ private:
17101710 bool _OctalDigits();
17111711 void _Do_ex_class(_Meta_type);
17121712 bool _CharacterClassEscape(bool);
1713- _Prs_ret _ClassEscape(bool );
1713+ _Prs_ret _ClassEscape2( );
17141714 _Prs_ret _ClassAtom();
17151715 void _ClassRanges();
17161716 void _CharacterClass();
@@ -4017,22 +4017,29 @@ bool _Parser<_FwdIt, _Elem, _RxTraits>::_CharacterClassEscape(bool _Addit) { //
40174017 return false;
40184018 }
40194019
4020+ const bool _Negated = _Traits.isctype(_Char, _RxTraits::_Ch_upper);
40204021 if (_Addit) {
40214022 _Nfa._Add_class();
4023+ // GH-992: Outside character class definitions, _Cls completely defines the character class
4024+ // so negating _Cls and negating the entire character class are equivalent.
4025+ // Since the former negation is defective, do the latter instead.
4026+ if (_Negated) {
4027+ _Nfa._Negate();
4028+ }
40224029 }
40234030
4024- _Nfa._Add_named_class(_Cls, _Traits.isctype(_Char, _RxTraits::_Ch_upper) );
4031+ _Nfa._Add_named_class(_Cls, _Negated && !_Addit );
40254032 _Next();
40264033 return true;
40274034}
40284035
40294036template <class _FwdIt, class _Elem, class _RxTraits>
4030- _Prs_ret _Parser<_FwdIt, _Elem, _RxTraits>::_ClassEscape(bool _Addit ) { // check for class escape
4037+ _Prs_ret _Parser<_FwdIt, _Elem, _RxTraits>::_ClassEscape2( ) { // check for class escape
40314038 if ((_L_flags & _L_esc_bsl) && _Char == _Esc_bsl) { // handle escape backslash if allowed
40324039 _Val = _Esc_bsl;
40334040 _Next();
40344041 return _Prs_chr;
4035- } else if ((_L_flags & _L_esc_wsd) && _CharacterClassEscape(_Addit )) {
4042+ } else if ((_L_flags & _L_esc_wsd) && _CharacterClassEscape(false )) {
40364043 return _Prs_set;
40374044 } else if (_DecimalDigits(regex_constants::error_escape)) { // check for invalid value
40384045 if (_Val != 0) {
@@ -4049,7 +4056,7 @@ _Prs_ret _Parser<_FwdIt, _Elem, _RxTraits>::_ClassAtom() { // check for class at
40494056 if (_Mchar == _Meta_esc) { // check for valid escape sequence
40504057 _Next();
40514058 if (_L_flags & _L_grp_esc) {
4052- return _ClassEscape(false );
4059+ return _ClassEscape2( );
40534060 } else if ((_L_flags & _L_esc_ffn && _Do_ffn(_Char))
40544061 || (_L_flags & _L_esc_ffnx && _Do_ffnx(_Char))) { // advance to next character
40554062 _Next();
0 commit comments