[patch] Avoid #ifdef _GLIBCXX_DEBUG in regex_compiler.h

Jonathan Wakely jwakely@redhat.com
Mon Sep 7 14:54:00 GMT 2015


We could go further and remove the ABI difference in regex_compiler
when using _GLIBCXX_DEBUG, as in the attached patch.

The trick is that for the char specialization we have padding bytes
between _M_is_non_matching (a bool) and _M_cache (a std::bitset), so
we can reuse one of those padding bytes for the _M_is_ready flag.

For the non-char specializations the _Dummy struct takes up one byte,
so we could reuse that for the _M_is_ready flag.

To be safe we should probably check that alignof(std::bitset<8> > 2)
so we know there really is a padding byte that can be re-used, and
place the _M_is_ready flag afterwards if there is no padding.

-------------- next part --------------
diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h
index 07a9ed3..9616d4e 100644
--- a/libstdc++-v3/include/bits/regex_compiler.h
+++ b/libstdc++-v3/include/bits/regex_compiler.h
@@ -369,13 +369,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _BracketMatcher(bool __is_non_matching,
 		      const _TraitsT& __traits)
       : _M_class_set(0), _M_translator(__traits), _M_traits(__traits),
-      _M_is_non_matching(__is_non_matching)
+      _M_extra_members(__is_non_matching)
       { }
 
       bool
       operator()(_CharT __ch) const
       {
-	_GLIBCXX_DEBUG_ASSERT(_M_is_ready);
+	_GLIBCXX_DEBUG_ASSERT(_M_extra._M_is_ready);
 	return _M_apply(__ch, _UseCache());
       }
 
@@ -383,7 +383,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_add_char(_CharT __c)
       {
 	_M_char_set.push_back(_M_translator._M_translate(__c));
-	_GLIBCXX_DEBUG_ONLY(_M_is_ready = false);
+	_GLIBCXX_DEBUG_ONLY(_M_extra._M_is_ready = false);
       }
 
       _StringT
@@ -394,7 +394,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	if (__st.empty())
 	  __throw_regex_error(regex_constants::error_collate);
 	_M_char_set.push_back(_M_translator._M_translate(__st[0]));
-	_GLIBCXX_DEBUG_ONLY(_M_is_ready = false);
+	_GLIBCXX_DEBUG_ONLY(_M_extra._M_is_ready = false);
 	return __st;
       }
 
@@ -408,7 +408,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	__st = _M_traits.transform_primary(__st.data(),
 					   __st.data() + __st.size());
 	_M_equiv_set.push_back(__st);
-	_GLIBCXX_DEBUG_ONLY(_M_is_ready = false);
+	_GLIBCXX_DEBUG_ONLY(_M_extra._M_is_ready = false);
       }
 
       // __neg should be true for \D, \S and \W only.
@@ -424,7 +424,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  _M_class_set |= __mask;
 	else
 	  _M_neg_class_set.push_back(__mask);
-	_GLIBCXX_DEBUG_ONLY(_M_is_ready = false);
+	_GLIBCXX_DEBUG_ONLY(_M_extra._M_is_ready = false);
       }
 
       void
@@ -434,7 +434,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  __throw_regex_error(regex_constants::error_range);
 	_M_range_set.push_back(make_pair(_M_translator._M_transform(__l),
 					 _M_translator._M_transform(__r)));
-	_GLIBCXX_DEBUG_ONLY(_M_is_ready = false);
+	_GLIBCXX_DEBUG_ONLY(_M_extra._M_is_ready = false);
       }
 
       void
@@ -444,7 +444,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	auto __end = std::unique(_M_char_set.begin(), _M_char_set.end());
 	_M_char_set.erase(__end, _M_char_set.end());
 	_M_make_cache(_UseCache());
-	_GLIBCXX_DEBUG_ONLY(_M_is_ready = true);
+	_GLIBCXX_DEBUG_ONLY(_M_extra._M_is_ready = true);
       }
 
     private:
@@ -457,10 +457,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	return 1ul << (sizeof(_CharT) * __CHAR_BIT__ * int(_UseCache::value));
       }
 
-      struct _Dummy { };
-      typedef typename std::conditional<_UseCache::value,
-					std::bitset<_S_cache_size()>,
-					_Dummy>::type _CacheT;
+      struct _Flags
+      {
+	bool _M_is_non_matching;
+	bool _M_is_ready;
+      };
+
+      struct _Empty { };
+
+      struct _ExtraMembers
+      : _Flags,
+	conditional<_UseCache::value, bitset<_S_cache_size()>, _Empty>::type
+      {
+	explicit
+	_ExtraMembers(bool __is_non_matching)
+	: _Flags{__is_non_matching, false}
+	{ }
+      };
+
       typedef typename std::make_unsigned<_CharT>::type _UnsignedCharT;
 
       bool
@@ -468,13 +482,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       bool
       _M_apply(_CharT __ch, true_type) const
-      { return _M_cache[static_cast<_UnsignedCharT>(__ch)]; }
+      { return _M_extra._M_cache[static_cast<_UnsignedCharT>(__ch)]; }
 
       void
       _M_make_cache(true_type)
       {
-	for (unsigned __i = 0; __i < _M_cache.size(); __i++)
-	  _M_cache[__i] = _M_apply(static_cast<_CharT>(__i), false_type());
+	auto& __cache = _M_extra._M_cache;
+	for (unsigned __i = 0; __i < __cache.size(); __i++)
+	  __cache[__i] = _M_apply(static_cast<_CharT>(__i), false_type());
       }
 
       void
@@ -489,11 +504,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _CharClassT                               _M_class_set;
       _TransT                                   _M_translator;
       const _TraitsT&                           _M_traits;
-      bool                                      _M_is_non_matching;
-      _CacheT					_M_cache;
-#ifdef _GLIBCXX_DEBUG
-      bool                                      _M_is_ready = false;
-#endif
+      _ExtraMembers				_M_extra;
     };
 
  //@} regex-detail


More information about the Libstdc++ mailing list