diff --git a/libcxx/include/__locale b/libcxx/include/__locale --- a/libcxx/include/__locale +++ b/libcxx/include/__locale @@ -496,7 +496,13 @@ static const mask punct = 1<<7; static const mask xdigit = 1<<8; static const mask blank = 1<<9; +#if defined(__BIONIC__) + // Historically this was a part of regex_traits rather than ctype_base. The + // historical value of the constant is preserved for ABI compatibility. + static const mask __regex_word = 0x8000; +#else static const mask __regex_word = 1<<10; +#endif // defined(__BIONIC__) #endif static const mask alnum = alpha | digit; static const mask graph = alnum | punct; diff --git a/libcxx/include/regex b/libcxx/include/regex --- a/libcxx/include/regex +++ b/libcxx/include/regex @@ -1000,7 +1000,19 @@ typedef _CharT char_type; typedef basic_string string_type; typedef locale locale_type; +#ifdef __BIONIC__ + // Originally bionic's ctype_base used its own ctype masks because the + // builtin ctype implementation wasn't in libc++ yet. Bionic's ctype mask + // was only 8 bits wide and already saturated, so it used a wider type here + // to make room for __regex_word (then a part of this class rather than + // ctype_base). Bionic has since moved to the builtin ctype_base + // implementation, but this was not updated to match. Since then Android has + // needed to maintain a stable libc++ ABI, and this can't be changed without + // an ABI break. + typedef uint16_t char_class_type; +#else typedef ctype_base::mask char_class_type; +#endif static const char_class_type __regex_word = ctype_base::__regex_word; private: