[v3,11/21] Compile suppression regexes earlier.

Message ID 20200424092132.150547-12-gprocida@google.com
State Superseded
Headers
Series Simplify regex and suppression parsing. |

Commit Message

Giuliano Procida April 24, 2020, 9:21 a.m. UTC
  Regexes are used in suppression specifications for various things.
They are currently compiled on first use, rather than on construction
of the specifications.

This patches changes the suppression specification types to hold
compiled regexes directly which is a significant simplification and is
a prerequisite for early error reporting.

There are no behavioural changes.

	* include/abg-suppression.h (suppression_base): In
	constructor, take regex arguments as regex_t_sptr. Replace all
	set_*_regex_str and get_*_regex_str methods with set_*_regex
	and get_*_regex methods.
	(type_suppression): In constructor, take regex arguments as
	regex_t_sptr. Replace all set_*_regex_str and get_*_regex_str
	methods with set_*_regex and get_*_regex methods.
	(function_suppression): In constructor, take regex arguments
	as regex_t_sptr. Replace all set_*_regex_str and
	get_*_regex_str methods with set_*_regex and get_*_regex
	methods.
	(function_suppression::parameter_spec): In constructor, take
	regex arguments as regex_t_sptr. Replace all set_*_regex_str and
	get_*_regex_str methods with set_*_regex and get_*_regex
	methods.
	(variable_suppression): In constructor, take regex arguments
	as regex_t_sptr. Replace all set_*_regex_str and get_*_regex_str
	methods with set_*_regex and get_*_regex methods.
	(file_suppression): In constructor, take regex arguments
	as regex_t_sptr.
	* src/abg-suppression-priv.h (suppression_base::priv): Drop
	all *_regex_str_ members. Drop mutable qualifier on
	all *_regex_ members. In constructor, take regexes instead of
	strings for regex arguments. Update all get_*_regex methods to
	remove regex compilation and update comments.
	(function_suppression::parameter_spec::priv): Drop
	all *_regex_str_ members. Drop mutable qualifier on
	all *_regex_ members. In constructor, take regexes instead of
	strings for regex arguments. Update get_*_regex methods to
	remove regex compilation and update comments.
	(function_suppression::priv): Drop all *_regex_str_ members.
	Drop mutable qualifier on all *_regex_ members. In constructor,
	take regexes instead of strings for regex arguments. Update
	all get_*_regex methods to remove regex compilation and
	update comments.
	(variable_suppression::priv): Drop all *_regex_str_ members.
	Drop mutable qualifier on all *_regex_ members. In
	constructor, take regexes instead of strings for regex
	arguments. Update all get_*_regex methods to remove
	regex compilation and update comments.
	(type_suppression::priv): Drop all *_regex_str_ members.
	Drop mutable qualifier on all *_regex_ members. In constructor,
	take regexes instead of strings for regex arguments. Update
	all get_*_regex methods to remove regex compilation and
	update comments. Drop set_type_name_regex_str and
	get_type_name_regex_str methods.
	* src/abg-suppression.cc (suppression_base): In constructor,
	take regexes instead of strings for regex arguments. Replace
	all set_*_regex_str and get_*_regex_str methods with
	set_*_regex and get_*_regex methods. Update
	has_file_name_related_property and has_soname_related_property
	methods.
	(type_suppression): In constructor, take regexes instead of
	strings for regex arguments. Replace all set_*_regex_str and
	get_*_regex_str methods with set_*_regex and get_*_regex
	methods. Update has_file_name_related_property and
	has_soname_related_property methods.
	(read_type_suppression): Compile regexes instead of keeping
	them as strings. Pass them to type_suppression constructor and
	setters.
	(function_suppression::parameter_spec): In constructor, take
	regexes instead of strings for regex arguments. Replace all
	set_*_regex_str and get_*_regex_str methods with set_*_regex and
	get_*_regex methods.
	(function_suppression): In constructor, take regexes instead
	of strings for regex arguments. Replace all set_*_regex_str
	and get_*_regex_str methods with set_*_regex and get_*_regex
	methods. Update suppresses_function_symbol method.
	(read_parameter_spec_from_string): Change type of
	type_name_regex from string to regex and compile when needed.
	(read_function_suppression): Compile regexes instead of
	keeping them as strings. Pass them to function_suppression
	constructor and setters.
	(variable_suppression): In constructor, take regexes instead
	of strings for regex arguments. Replace all set_*_regex_str
	and get_*_regex_str methods with set_*_regex and get_*_regex
	methods.
	(file_suppression): In constructor, take regexes instead of
	strings for regex arguments. Replace all set_*_regex_str and
	get_*_regex_str methods with set_*_regex and get_*_regex
	methods.
	* src/abg-tools-utils.cc (handle_file_entry): Compile and
	check regex for /usr/include.
	(gen_suppr_spec_from_kernel_abi_whitelists):
	Compile and check whitelisting regex.
	* tests/test-kmi-whitelist.cc (random_symbols) Add array of
	symbols. (test_suppressions_are_consistent): Rework to test by
	matching regexes against symbols, now that uncompiled regex
	strings are no longer available.

Signed-off-by: Giuliano Procida <gprocida@google.com>
---
 include/abg-suppression.h   | 165 ++++-----
 src/abg-suppression-priv.h  | 357 ++++---------------
 src/abg-suppression.cc      | 694 ++++++++++++++++++------------------
 src/abg-tools-utils.cc      |  17 +-
 tests/test-kmi-whitelist.cc |  60 +++-
 5 files changed, 583 insertions(+), 710 deletions(-)
  

Patch

diff --git a/include/abg-suppression.h b/include/abg-suppression.h
index 4f1fb417..1869cbe5 100644
--- a/include/abg-suppression.h
+++ b/include/abg-suppression.h
@@ -26,6 +26,7 @@ 
 #include "abg-cxx-compat.h"
 #include "abg-ini.h"
 #include "abg-comparison.h"
+#include "abg-regex.h"
 
 namespace abigail
 {
@@ -64,8 +65,8 @@  public:
   suppression_base(const string& label);
 
   suppression_base(const string& label,
-		   const string& file_name_regex_str,
-		   const string& file_name_not_regex_str);
+		   const regex::regex_t_sptr& file_name_regex,
+		   const regex::regex_t_sptr& file_name_not_regex);
 
   bool
   get_drops_artifact_from_ir() const;
@@ -86,31 +87,31 @@  public:
   set_label(const string&);
 
   void
-  set_file_name_regex_str(const string& regexp);
+  set_file_name_regex(const regex::regex_t_sptr& regexp);
 
-  const string&
-  get_file_name_regex_str() const;
+  const regex::regex_t_sptr&
+  get_file_name_regex() const;
 
   void
-  set_file_name_not_regex_str(const string& regexp);
+  set_file_name_not_regex(const regex::regex_t_sptr& regexp);
 
-  const string&
-  get_file_name_not_regex_str() const;
+  const regex::regex_t_sptr&
+  get_file_name_not_regex() const;
 
   bool
   has_file_name_related_property() const;
 
   void
-  set_soname_regex_str(const string& regexp);
+  set_soname_regex(const regex::regex_t_sptr& regexp);
 
-  const string&
-  get_soname_regex_str() const;
+  const regex::regex_t_sptr&
+  get_soname_regex() const;
 
   void
-  set_soname_not_regex_str(const string& regexp);
+  set_soname_not_regex(const regex::regex_t_sptr& regexp);
 
-  const string&
-  get_soname_not_regex_str() const;
+  const regex::regex_t_sptr&
+  get_soname_not_regex() const;
 
   bool
   has_soname_related_property() const;
@@ -204,22 +205,22 @@  public:
   typedef vector<insertion_range_sptr> insertion_ranges;
 
   type_suppression(const string& label,
-		   const string& type_name_regexp,
+		   const regex::regex_t_sptr& type_name_regexp,
 		   const string& type_name);
 
   virtual ~type_suppression();
 
   void
-  set_type_name_regex_str(const string& name_regex_str);
+  set_type_name_regex(const regex::regex_t_sptr& name_regex);
 
-  const string&
-  get_type_name_regex_str() const;
+  const regex::regex_t_sptr&
+  get_type_name_regex() const;
 
   void
-  set_type_name_not_regex_str(const string& name_regex_str);
+  set_type_name_not_regex(const regex::regex_t_sptr& name_regex);
 
-  const string&
-  get_type_name_not_regex_str() const;
+  const regex::regex_t_sptr&
+  get_type_name_not_regex() const;
 
   void
   set_type_name(const string& name);
@@ -269,11 +270,11 @@  public:
   void
   set_source_locations_to_keep(const unordered_set<string>&);
 
-  const string&
-  get_source_location_to_keep_regex_str() const;
+  const regex::regex_t_sptr&
+  get_source_location_to_keep_regex() const;
 
   void
-  set_source_location_to_keep_regex_str(const string&);
+  set_source_location_to_keep_regex(const regex::regex_t_sptr&);
 
   const vector<string>&
   get_changed_enumerator_names() const;
@@ -460,16 +461,16 @@  public:
 
   function_suppression();
 
-  function_suppression(const string&		label,
-		       const string&		name,
-		       const string&		name_regex,
-		       const string&		return_type_name,
-		       const string&		return_type_regex,
-		       parameter_specs_type&	parm_specs,
-		       const string&		symbol_name,
-		       const string&		symbol_name_regex,
-		       const string&		symbol_version,
-		       const string&		symbol_version_regex_str);
+  function_suppression(const string&			label,
+		       const string&			name,
+		       const regex::regex_t_sptr&	name_regex,
+		       const string&			return_type_name,
+		       const regex::regex_t_sptr&	return_type_regex,
+		       parameter_specs_type&		parm_specs,
+		       const string&			symbol_name,
+		       const regex::regex_t_sptr&	symbol_name_regex,
+		       const string&			symbol_version,
+		       const regex::regex_t_sptr&	symbol_version_regex);
 
   virtual ~function_suppression();
 
@@ -488,17 +489,17 @@  public:
   void
   set_name(const string&);
 
-  const string&
-  get_name_regex_str() const;
+  const regex::regex_t_sptr&
+  get_name_regex() const;
 
   void
-  set_name_regex_str(const string&);
+  set_name_regex(const regex::regex_t_sptr&);
 
-  const string&
-  get_name_not_regex_str() const;
+  const regex::regex_t_sptr&
+  get_name_not_regex() const;
 
   void
-  set_name_not_regex_str(const string&);
+  set_name_not_regex(const regex::regex_t_sptr&);
 
   const string&
   get_return_type_name() const;
@@ -506,11 +507,11 @@  public:
   void
   set_return_type_name(const string&);
 
-  const string&
-  get_return_type_regex_str() const;
+  const regex::regex_t_sptr&
+  get_return_type_regex() const;
 
   void
-  set_return_type_regex_str(const string& r);
+  set_return_type_regex(const regex::regex_t_sptr& r);
 
   const parameter_specs_type&
   get_parameter_specs() const;
@@ -527,17 +528,17 @@  public:
   void
   set_symbol_name(const string& n);
 
-  const string&
-  get_symbol_name_regex_str() const;
+  const regex::regex_t_sptr&
+  get_symbol_name_regex() const;
 
   void
-  set_symbol_name_regex_str(const string&);
+  set_symbol_name_regex(const regex::regex_t_sptr&);
 
-  const string&
-  get_symbol_name_not_regex_str() const;
+  const regex::regex_t_sptr&
+  get_symbol_name_not_regex() const;
 
   void
-  set_symbol_name_not_regex_str(const string&);
+  set_symbol_name_not_regex(const regex::regex_t_sptr&);
 
   const string&
   get_symbol_version() const;
@@ -545,11 +546,11 @@  public:
   void
   set_symbol_version(const string&);
 
-  const string&
-  get_symbol_version_regex_str() const;
+  const regex::regex_t_sptr&
+  get_symbol_version_regex() const;
 
   void
-  set_symbol_version_regex_str(const string&);
+  set_symbol_version_regex(const regex::regex_t_sptr&);
 
   bool
   get_allow_other_aliases() const;
@@ -609,7 +610,7 @@  class function_suppression::parameter_spec
 public:
   parameter_spec(size_t index,
 		 const string& type_name,
-		 const string& type_name_regex);
+		 const regex::regex_t_sptr& type_name_regex);
 
   size_t
   get_index() const;
@@ -623,11 +624,11 @@  public:
   void
   set_parameter_type_name(const string&);
 
-  const string&
-  get_parameter_type_name_regex_str() const;
+  const regex::regex_t_sptr&
+  get_parameter_type_name_regex() const;
 
   void
-  set_parameter_type_name_regex_str(const string&);
+  set_parameter_type_name_regex(const regex::regex_t_sptr&);
 };// end class function_suppression::parameter_spec
 
 class variable_suppression;
@@ -679,13 +680,17 @@  public:
 
   variable_suppression(const string& label = "",
 		       const string& name = "",
-		       const string& name_regex_str = "",
+		       const regex::regex_t_sptr& name_regex =
+			 regex::regex_t_sptr(),
 		       const string& symbol_name = "",
-		       const string& symbol_name_regex_str = "",
+		       const regex::regex_t_sptr& symbol_name_regex =
+			 regex::regex_t_sptr(),
 		       const string& symbol_version = "",
-		       const string& symbol_version_regex_str = "",
+		       const regex::regex_t_sptr& symbol_version_regex =
+			 regex::regex_t_sptr(),
 		       const string& type_name = "",
-		       const string& type_name_regex_str = "");
+		       const regex::regex_t_sptr& type_name_regex =
+			 regex::regex_t_sptr());
 
   virtual ~variable_suppression();
 
@@ -704,17 +709,17 @@  public:
   void
   set_name(const string&);
 
-  const string&
-  get_name_regex_str() const;
+  const regex::regex_t_sptr&
+  get_name_regex() const;
 
   void
-  set_name_regex_str(const string&);
+  set_name_regex(const regex::regex_t_sptr&);
 
-  const string&
-  get_name_not_regex_str() const;
+  const regex::regex_t_sptr&
+  get_name_not_regex() const;
 
   void
-  set_name_not_regex_str(const string&);
+  set_name_not_regex(const regex::regex_t_sptr&);
 
   const string&
   get_symbol_name() const;
@@ -722,17 +727,17 @@  public:
   void
   set_symbol_name(const string&);
 
-  const string&
-  get_symbol_name_regex_str() const;
+  const regex::regex_t_sptr&
+  get_symbol_name_regex() const;
 
   void
-  set_symbol_name_regex_str(const string&);
+  set_symbol_name_regex(const regex::regex_t_sptr&);
 
-  const string&
-  get_symbol_name_not_regex_str() const;
+  const regex::regex_t_sptr&
+  get_symbol_name_not_regex() const;
 
   void
-  set_symbol_name_not_regex_str(const string&);
+  set_symbol_name_not_regex(const regex::regex_t_sptr&);
 
   const string&
   get_symbol_version() const;
@@ -740,11 +745,11 @@  public:
   void
   set_symbol_version(const string&);
 
-  const string&
-  get_symbol_version_regex_str() const;
+  const regex::regex_t_sptr&
+  get_symbol_version_regex() const;
 
   void
-  set_symbol_version_regex_str(const string&);
+  set_symbol_version_regex(const regex::regex_t_sptr&);
 
   const string&
   get_type_name() const;
@@ -752,11 +757,11 @@  public:
   void
   set_type_name(const string&);
 
-  const string&
-  get_type_name_regex_str() const;
+  const regex::regex_t_sptr&
+  get_type_name_regex() const;
 
   void
-  set_type_name_regex_str(const string&);
+  set_type_name_regex(const regex::regex_t_sptr&);
 
   bool
   suppresses_diff(const diff* d) const;
@@ -816,8 +821,8 @@  class file_suppression: public suppression_base
 public:
 
   file_suppression(const string& label,
-		   const string& file_name_regex,
-		   const string& file_name_not_regex);
+		   const regex::regex_t_sptr& file_name_regex,
+		   const regex::regex_t_sptr& file_name_not_regex);
 
   virtual bool
   suppresses_diff(const diff* diff) const;
diff --git a/src/abg-suppression-priv.h b/src/abg-suppression-priv.h
index 8043ebd9..263052d4 100644
--- a/src/abg-suppression-priv.h
+++ b/src/abg-suppression-priv.h
@@ -47,14 +47,10 @@  class suppression_base::priv
   bool					is_artificial_;
   bool					drops_artifact_;
   string				label_;
-  string				file_name_regex_str_;
-  mutable regex::regex_t_sptr		file_name_regex_;
-  string				file_name_not_regex_str_;
-  mutable regex::regex_t_sptr		file_name_not_regex_;
-  string				soname_regex_str_;
-  mutable regex::regex_t_sptr		soname_regex_;
-  string				soname_not_regex_str_;
-  mutable regex::regex_t_sptr		soname_not_regex_;
+  regex::regex_t_sptr			file_name_regex_;
+  regex::regex_t_sptr			file_name_not_regex_;
+  regex::regex_t_sptr			soname_regex_;
+  regex::regex_t_sptr			soname_not_regex_;
 
 public:
   priv()
@@ -69,78 +65,46 @@  public:
   {}
 
   priv(const string& label,
-       const string& file_name_regex_str,
-       const string& file_name_not_regex_str)
+       const regex::regex_t_sptr& file_name_regex,
+       const regex::regex_t_sptr& file_name_not_regex)
     : is_artificial_(),
       drops_artifact_(),
       label_(label),
-      file_name_regex_str_(file_name_regex_str),
-      file_name_not_regex_str_(file_name_not_regex_str)
+      file_name_regex_(file_name_regex),
+      file_name_not_regex_(file_name_not_regex)
   {}
 
   friend class suppression_base;
 
-  /// Get the regular expression object associated to the 'file_name_regex'
-  /// property of @ref suppression_base.
-  ///
-  /// If the regular expression object is not created, this method
-  /// creates it and returns it.
-  ///
-  /// If the 'file_name_regex' property of @ref suppression_base is
-  /// empty then this method returns nil.
+  /// Get the regular expression object associated to the
+  /// 'file_name_regex' property of @ref suppression_base.
   const regex::regex_t_sptr&
   get_file_name_regex() const
   {
-    if (!file_name_regex_ && !file_name_regex_str_.empty())
-      file_name_regex_ = regex::compile(file_name_regex_str_);
     return file_name_regex_;
   }
 
   /// Get the regular expression object associated to the
   /// 'file_name_not_regex' property of @ref suppression_base.
-  ///
-  /// If the regular expression object is not created, this method
-  /// creates it and returns it.
-  ///
-  /// If the 'file_name_not_regex' property of @ref suppression_base
-  /// is empty then this method returns nil.
   const regex::regex_t_sptr&
   get_file_name_not_regex() const
   {
-    if (!file_name_not_regex_ && !file_name_not_regex_str_.empty())
-      file_name_not_regex_ = regex::compile(file_name_not_regex_str_);
     return file_name_not_regex_;
   }
 
-  /// Get the regular expression object associated to the
-  /// 'soname_regex' property of @ref suppression_base.
-  ///
-  /// If the regular expression object is not created, this method
-  /// creates it and returns it.
-  ///
-  /// If the 'soname_regex' property of @ref suppression_base is empty
-  /// then this method returns nil.
+  /// Get the regular expression object associated to the 'soname_regex'
+  /// property of @ref suppression_base.
   const regex::regex_t_sptr&
   get_soname_regex() const
   {
-    if (!soname_regex_ && !soname_regex_str_.empty())
-      soname_regex_ = regex::compile(soname_regex_str_);
     return soname_regex_;
   }
 
   /// Get the regular expression object associated to the
   /// 'soname_not_regex' property of @ref suppression_base.
-  ///
-  /// If the regular expression object is not created, this method
-  /// creates it and returns it.
-  ///
-  /// If the 'soname_not_regex' property of @ref suppression_base is
-  /// empty then this method returns nil.
   const regex::regex_t_sptr&
   get_soname_not_regex() const
   {
-    if (!soname_not_regex_ && !soname_not_regex_str_.empty())
-      soname_not_regex_ = regex::compile(soname_not_regex_str_);
     return soname_not_regex_;
   }
 
@@ -225,8 +189,7 @@  class function_suppression::parameter_spec::priv
 
   size_t				index_;
   string				type_name_;
-  string				type_name_regex_str_;
-  mutable regex::regex_t_sptr		type_name_regex_;
+  regex::regex_t_sptr			type_name_regex_;
 
   priv()
     : index_()
@@ -236,15 +199,16 @@  class function_suppression::parameter_spec::priv
     : index_(i), type_name_(tn)
   {}
 
-  priv(size_t i, const string& tn, const string& tn_regex)
-    : index_(i), type_name_(tn), type_name_regex_str_(tn_regex)
+  priv(size_t i, const string& tn, const regex::regex_t_sptr& tn_regex)
+    : index_(i), type_name_(tn), type_name_regex_(tn_regex)
   {}
 
+  /// Get the regular expression object associated to the
+  /// 'type_name_regex' property of @ref
+  /// function_suppression::parameter_spec.
   const regex::regex_t_sptr
   get_type_name_regex() const
   {
-    if (!type_name_regex_ && !type_name_regex_str_.empty())
-      type_name_regex_ = regex::compile(type_name_regex_str_);
     return type_name_regex_;
   }
 }; // end class function_suppression::parameter_spec::priv
@@ -258,22 +222,16 @@  struct function_suppression::priv
 
   change_kind				change_kind_;
   string				name_;
-  string				name_regex_str_;
-  mutable regex::regex_t_sptr		name_regex_;
-  string				name_not_regex_str_;
-  mutable regex::regex_t_sptr		name_not_regex_;
+  regex::regex_t_sptr			name_regex_;
+  regex::regex_t_sptr			name_not_regex_;
   string				return_type_name_;
-  string				return_type_regex_str_;
-  mutable regex::regex_t_sptr		return_type_regex_;
+  regex::regex_t_sptr			return_type_regex_;
   parameter_specs_type			parm_specs_;
   string				symbol_name_;
-  string				symbol_name_regex_str_;
-  mutable regex::regex_t_sptr		symbol_name_regex_;
-  string				symbol_name_not_regex_str_;
-  mutable regex::regex_t_sptr		symbol_name_not_regex_;
+  regex::regex_t_sptr			symbol_name_regex_;
+  regex::regex_t_sptr			symbol_name_not_regex_;
   string				symbol_version_;
-  string				symbol_version_regex_str_;
-  mutable regex::regex_t_sptr		symbol_version_regex_;
+  regex::regex_t_sptr			symbol_version_regex_;
   bool					allow_other_aliases_;
 
   priv():
@@ -282,127 +240,72 @@  struct function_suppression::priv
   {}
 
   priv(const string&			name,
-       const string&			name_regex_str,
+       const regex::regex_t_sptr&	name_regex,
        const string&			return_type_name,
-       const string&			return_type_regex_str,
+       const regex::regex_t_sptr&	return_type_regex,
        const parameter_specs_type&	parm_specs,
        const string&			symbol_name,
-       const string&			symbol_name_regex_str,
+       const regex::regex_t_sptr&	symbol_name_regex,
        const string&			symbol_version,
-       const string&			symbol_version_regex_str)
+       const regex::regex_t_sptr&	symbol_version_regex)
     : change_kind_(ALL_CHANGE_KIND),
       name_(name),
-      name_regex_str_(name_regex_str),
+      name_regex_(name_regex),
       return_type_name_(return_type_name),
-      return_type_regex_str_(return_type_regex_str),
+      return_type_regex_(return_type_regex),
       parm_specs_(parm_specs),
       symbol_name_(symbol_name),
-      symbol_name_regex_str_(symbol_name_regex_str),
+      symbol_name_regex_(symbol_name_regex),
       symbol_version_(symbol_version),
-      symbol_version_regex_str_(symbol_version_regex_str),
+      symbol_version_regex_(symbol_version_regex),
       allow_other_aliases_(true)
   {}
 
-
-  /// Getter for a pointer to a regular expression object built from
-  /// the regular expression string
-  /// function_suppression::priv::name_regex_str_.
-  ///
-  /// If that string is empty, then an empty regular expression object
-  /// pointer is returned.
-  ///
-  /// @return a pointer to the regular expression object of
-  /// function_suppression::priv::name_regex_str_..
+  /// Get the regular expression object associated to the 'name_regex'
+  /// property of @ref function_suppression.
   const regex::regex_t_sptr
   get_name_regex() const
   {
-    if (!name_regex_ && !name_regex_str_.empty())
-      name_regex_ = regex::compile(name_regex_str_);
     return name_regex_;
   }
 
-  /// Getter for a pointer to a regular expression object built from
-  /// the regular expression string
-  /// function_suppression::priv::name_not_regex_str_.
-  ///
-  /// If that string is empty, then an empty regular expression object
-  /// pointer is returned.
-  ///
-  /// @return a pointer to the regular expression object of
-  /// function_suppression::priv::name_not_regex_str_..
+  /// Get the regular expression object associated to the
+  /// 'name_not_regex' property of @ref function_suppression.
   const regex::regex_t_sptr
   get_name_not_regex() const
   {
-    if (!name_not_regex_ && !name_not_regex_str_.empty())
-      name_not_regex_ = regex::compile(name_not_regex_str_);
     return name_not_regex_;
   }
 
-  /// Getter for a pointer to a regular expression object built from
-  /// the regular expression string
-  /// function_suppression::priv::return_type_regex_str_.
-  ///
-  /// If that string is empty, then an empty regular expression object
-  /// pointer is returned.
-  ///
-  /// @return a pointer to the regular expression object of
-  /// function_suppression::priv::return_type_regex_str_.
+  /// Get the regular expression object associated to the
+  /// 'return_type_regex' property of @ref function_suppression.
   const regex::regex_t_sptr
   get_return_type_regex() const
   {
-    if (!return_type_regex_ && !return_type_regex_str_.empty())
-      return_type_regex_ = regex::compile(return_type_regex_str_);
     return return_type_regex_;
   }
 
-  /// Getter for a pointer to a regular expression object built from
-  /// the regular expression string
-  /// function_suppression::priv::symbol_name_regex_str_.
-  ///
-  /// If that string is empty, then an empty regular expression object
-  /// pointer is returned.
-  ///
-  /// @return a pointer to the regular expression object of
-  /// function_suppression::priv::symbol_name_regex_str_.
+  /// Get the regular expression object associated to the
+  /// 'symbol_name_regex' property of @ref function_suppression.
   const regex::regex_t_sptr
   get_symbol_name_regex() const
   {
-    if (!symbol_name_regex_ && !symbol_name_regex_str_.empty())
-      symbol_name_regex_ = regex::compile(symbol_name_regex_str_);
     return symbol_name_regex_;
   }
 
-  /// Getter for a pointer to a regular expression object built from
-  /// the regular expression string
-  /// function_suppression::priv::symbol_name_not_regex_str_.
-  ///
-  /// If that string is empty, then an empty regular expression object
-  /// pointer is returned.
-  ///
-  /// @return a pointer to the regular expression object of
-  /// function_suppression::priv::symbol_name_not_regex_str_.
+  /// Get the regular expression object associated to the
+  /// 'symbol_name_not_regex' property of @ref function_suppression.
   const regex::regex_t_sptr
   get_symbol_name_not_regex() const
   {
-    if (!symbol_name_not_regex_ && !symbol_name_not_regex_str_.empty())
-      symbol_name_not_regex_ = regex::compile(symbol_name_not_regex_str_);
     return symbol_name_not_regex_;
   }
 
-  /// Getter for a pointer to a regular expression object built from
-  /// the regular expression string
-  /// function_suppression::priv::symbol_version_regex_str_.
-  ///
-  /// If that string is empty, then an empty regular expression object
-  /// pointer is returned.
-  ///
-  /// @return a pointer to the regular expression object of
-  /// function_suppression::priv::symbol_version_regex_str_.
+  /// Get the regular expression object associated to the
+  /// 'symbol_version_regex' property of @ref function_suppression.
   const regex::regex_t_sptr
   get_symbol_version_regex() const
   {
-    if (!symbol_version_regex_ && !symbol_version_regex_str_.empty())
-      symbol_version_regex_ = regex::compile(symbol_version_regex_str_);
     return symbol_version_regex_;
   }
 }; // end class function_suppression::priv
@@ -481,140 +384,80 @@  struct variable_suppression::priv
 
   change_kind				change_kind_;
   string				name_;
-  string				name_regex_str_;
-  mutable regex::regex_t_sptr		name_regex_;
-  string				name_not_regex_str_;
-  mutable regex::regex_t_sptr		name_not_regex_;
+  regex::regex_t_sptr			name_regex_;
+  regex::regex_t_sptr			name_not_regex_;
   string				symbol_name_;
-  string				symbol_name_regex_str_;
-  mutable regex::regex_t_sptr		symbol_name_regex_;
-  string				symbol_name_not_regex_str_;
-  mutable regex::regex_t_sptr		symbol_name_not_regex_;
+  regex::regex_t_sptr			symbol_name_regex_;
+  regex::regex_t_sptr			symbol_name_not_regex_;
   string				symbol_version_;
-  string				symbol_version_regex_str_;
-  mutable regex::regex_t_sptr		symbol_version_regex_;
+  regex::regex_t_sptr			symbol_version_regex_;
   string				type_name_;
-  string				type_name_regex_str_;
-  mutable regex::regex_t_sptr		type_name_regex_;
+  regex::regex_t_sptr			type_name_regex_;
 
   priv(const string& name,
-       const string& name_regex_str,
+       const regex::regex_t_sptr& name_regex,
        const string& symbol_name,
-       const string& symbol_name_regex_str,
+       const regex::regex_t_sptr& symbol_name_regex,
        const string& symbol_version,
-       const string& symbol_version_regex_str,
+       const regex::regex_t_sptr& symbol_version_regex,
        const string& type_name,
-       const string& type_name_regex_str)
+       const regex::regex_t_sptr& type_name_regex)
     : change_kind_(ALL_CHANGE_KIND),
       name_(name),
-      name_regex_str_(name_regex_str),
+      name_regex_(name_regex),
       symbol_name_(symbol_name),
-      symbol_name_regex_str_(symbol_name_regex_str),
+      symbol_name_regex_(symbol_name_regex),
       symbol_version_(symbol_version),
-      symbol_version_regex_str_(symbol_version_regex_str),
+      symbol_version_regex_(symbol_version_regex),
       type_name_(type_name),
-      type_name_regex_str_(type_name_regex_str)
+      type_name_regex_(type_name_regex)
   {}
 
-  /// Getter for a pointer to a regular expression object built from
-  /// the regular expression string
-  /// variable_suppression::priv::name_regex_str_.
-  ///
-  /// If that string is empty, then an empty regular expression object
-  /// pointer is returned.
-  ///
-  /// @return a pointer to the regular expression object of
-  /// variable_suppression::priv::name_regex_str_.
+  /// Get the regular expression object associated to the 'name_regex'
+  /// property of @ref variable_suppression.
   const regex::regex_t_sptr
   get_name_regex() const
   {
-    if (!name_regex_ && !name_regex_str_.empty())
-      name_regex_ = regex::compile(name_regex_str_);
     return name_regex_;
   }
 
-  /// Getter for a pointer to a regular expression object built from
-  /// the regular expression string
-  /// variable_suppression::priv::name_not_regex_str_.
-  ///
-  /// If that string is empty, then an empty regular expression object
-  /// pointer is returned.
-  ///
-  /// @return a pointer to the regular expression object of
-  /// variable_suppression::priv::name_not_regex_str_..
+  /// Get the regular expression object associated to the
+  /// 'name_not_regex' property of @ref variable_suppression.
   const regex::regex_t_sptr
   get_name_not_regex() const
   {
-    if (!name_not_regex_ && !name_not_regex_str_.empty())
-      name_not_regex_ = regex::compile(name_not_regex_str_);
     return name_not_regex_;
   }
 
-  /// Getter for a pointer to a regular expression object built from
-  /// the regular expression string
-  /// variable_suppression::priv::symbol_name_regex_str_.
-  ///
-  /// If that string is empty, then an empty regular expression object
-  /// pointer is returned.
-  ///
-  /// @return a pointer to the regular expression object of
-  /// variable_suppression::priv::symbol_name_regex_str_.
+  /// Get the regular expression object associated to the
+  /// 'symbol_name_regex' property of @ref variable_suppression.
   const regex::regex_t_sptr
   get_symbol_name_regex() const
   {
-    if (!symbol_name_regex_ && !symbol_name_regex_str_.empty())
-      symbol_name_regex_ = regex::compile(symbol_name_regex_str_);
     return symbol_name_regex_;
   }
 
-  /// Getter for a pointer to a regular expression object built from
-  /// the regular expression string
-  /// variable_suppression::priv::symbol_name_not_regex_str_.
-  ///
-  /// If that string is empty, then an empty regular expression object
-  /// pointer is returned.
-  ///
-  /// @return a pointer to the regular expression object of
-  /// variable_suppression::priv::symbol_name_not_regex_str_.
+  /// Get the regular expression object associated to the
+  /// 'symbol_name_not_regex' property of @ref variable_suppression.
   const regex::regex_t_sptr
   get_symbol_name_not_regex() const
   {
-    if (!symbol_name_not_regex_ && !symbol_name_not_regex_str_.empty())
-      symbol_name_not_regex_ = regex::compile(symbol_name_not_regex_str_);
     return symbol_name_not_regex_;
   }
 
-  /// Getter for a pointer to a regular expression object built from
-  /// the regular expression string
-  /// variable_suppression::priv::symbol_version_regex_str_.
-  ///
-  /// If that string is empty, then an empty regular expression object
-  /// pointer is returned.
-  ///
-  /// @return a pointer to the regular expression object of
-  /// variable_suppression::priv::symbol_version_regex_str_.
+  /// Get the regular expression object associated to the
+  /// 'symbol_version_regex' property of @ref variable_suppression.
   const regex::regex_t_sptr
   get_symbol_version_regex()  const
   {
-    if (!symbol_version_regex_ && !symbol_version_regex_str_.empty())
-      symbol_version_regex_ = regex::compile(symbol_version_regex_str_);
     return symbol_version_regex_;
   }
 
-  /// Getter for a pointer to a regular expression object built from
-  /// the regular expression string
-  /// variable_suppression::priv::type_name_regex_str_.
-  ///
-  /// If that string is empty, then an empty regular expression object
-  /// pointer is returned.
-  ///
-  /// @return a pointer to the regular expression object of
-  /// variable_suppression::priv::type_name_regex_str_.
+  /// Get the regular expression object associated to the
+  /// 'type_name_regex' property of @ref variable_suppression.
   const regex::regex_t_sptr
   get_type_name_regex() const
   {
-    if (!type_name_regex_ && !type_name_regex_str_.empty())
-      type_name_regex_ = regex::compile(type_name_regex_str_);
     return type_name_regex_;
   }
 };// end class variable_supppression::priv
@@ -651,31 +494,28 @@  variable_is_suppressed(const ReadContextType&	ctxt,
 /// The private data for @ref type_suppression.
 class type_suppression::priv
 {
-  string				type_name_regex_str_;
-  mutable regex::regex_t_sptr		type_name_regex_;
+  regex::regex_t_sptr			type_name_regex_;
   string				type_name_;
-  string				type_name_not_regex_str_;
-  mutable regex::regex_t_sptr		type_name_not_regex_;
+  regex::regex_t_sptr			type_name_not_regex_;
   bool					consider_type_kind_;
   type_suppression::type_kind		type_kind_;
   bool					consider_reach_kind_;
   type_suppression::reach_kind		reach_kind_;
   type_suppression::insertion_ranges	insertion_ranges_;
   unordered_set<string>			source_locations_to_keep_;
-  string				source_location_to_keep_regex_str_;
-  mutable regex::regex_t_sptr		source_location_to_keep_regex_;
+  regex::regex_t_sptr			source_location_to_keep_regex_;
   mutable vector<string>		changed_enumerator_names_;
 
   priv();
 
 public:
-  priv(const string&			type_name_regexp,
+  priv(const regex::regex_t_sptr&	type_name_regexp,
        const string&			type_name,
        bool				consider_type_kind,
        type_suppression::type_kind	type_kind,
        bool				consider_reach_kind,
        type_suppression::reach_kind	reach_kind)
-    : type_name_regex_str_(type_name_regexp),
+    : type_name_regex_(type_name_regexp),
       type_name_(type_name),
       consider_type_kind_(consider_type_kind),
       type_kind_(type_kind),
@@ -683,19 +523,11 @@  public:
       reach_kind_(reach_kind)
   {}
 
-  /// Get the regular expression object associated to the 'type_name_regex'
-  /// property of @ref type_suppression.
-  ///
-  /// If the regular expression object is not created, this method
-  /// creates it and returns it.
-  ///
-  /// If the 'type_name_regex' property of @ref type_suppression is
-  /// empty then this method returns nil.
+  /// Get the regular expression object associated to the
+  /// 'type_name_regex' property of @ref type_suppression.
   const regex::regex_t_sptr
   get_type_name_regex() const
   {
-    if (!type_name_regex_ && !type_name_regex_str_.empty())
-      type_name_regex_ = regex::compile(type_name_regex_str_);
     return type_name_regex_;
   }
 
@@ -708,17 +540,9 @@  public:
 
   /// Get the regular expression object associated to the
   /// 'type_name_not_regex' property of @ref type_suppression.
-  ///
-  /// If the regular expression object is not created, this method
-  /// creates it and returns it.
-  ///
-  /// If the 'type_name_not_regex' property of @ref type_suppression is
-  /// empty then this method returns nil.
   const regex::regex_t_sptr
   get_type_name_not_regex() const
   {
-    if (!type_name_not_regex_ && !type_name_not_regex_str_.empty())
-      type_name_not_regex_ = regex::compile(type_name_not_regex_str_);
     return type_name_not_regex_;
   }
 
@@ -729,34 +553,11 @@  public:
   set_type_name_not_regex(regex::regex_t_sptr r)
   {type_name_not_regex_ = r;}
 
-  /// Getter for the string that denotes the 'type_name_not_regex'
-  /// property.
-  ///
-  /// @return the value of the string value of the
-  /// 'type_name_not_regex' property.
-  const string&
-  get_type_name_not_regex_str() const
-  {return type_name_not_regex_str_;}
-
-  /// Setter for the string that denotes the 'type_name_not_regex'
-  /// property.
-  ///
-  /// @return the value of the string value of the
-  /// 'type_name_not_regex' property.
-  void
-  set_type_name_not_regex_str(const string regex_str)
-  {type_name_not_regex_str_ = regex_str;}
-
-  /// Getter for the source_location_to_keep_regex object.
-  ///
-  /// This function builds the regex if it's not yet built.
+  /// Get the regular expression object associated to the
+  /// 'source_location_to_keep_regex' property of @ref type_suppression.
   const regex::regex_t_sptr
   get_source_location_to_keep_regex() const
   {
-    if (!source_location_to_keep_regex_
-	&& !source_location_to_keep_regex_str_.empty())
-      source_location_to_keep_regex_ =
-	  regex::compile(source_location_to_keep_regex_str_);
     return source_location_to_keep_regex_;
   }
 
diff --git a/src/abg-suppression.cc b/src/abg-suppression.cc
index c389ed02..6953c18b 100644
--- a/src/abg-suppression.cc
+++ b/src/abg-suppression.cc
@@ -66,17 +66,17 @@  suppression_base::suppression_base(const string& label)
 /// @param a label for the suppression.  This represents just a
 /// comment.
 ///
-/// @param file_name_regex_str the regular expression that denotes the
+/// @param file_name_regex the regular expression that denotes the
 /// file name to match.
 ///
-/// @param file_name_not_regex_str the regular expression that denotes
+/// @param file_name_not_regex the regular expression that denotes
 /// the file name to *NOT* match.
 suppression_base::suppression_base(const string& label,
-				   const string& file_name_regex_str,
-				   const string& file_name_not_regex_str)
+				   const regex_t_sptr& file_name_regex,
+				   const regex_t_sptr& file_name_not_regex)
   : priv_(new priv(label,
-		   file_name_regex_str,
-		   file_name_not_regex_str))
+		   file_name_regex,
+		   file_name_not_regex))
 {
 }
 
@@ -138,52 +138,50 @@  suppression_base::set_label(const string& label)
 /// Setter for the "file_name_regex" property of the current instance
 /// of @ref suppression_base.
 ///
-/// The "file_name_regex" property is a regular expression string that
+/// The "file_name_regex" property is a regular expression that
 /// designates the file name that contains the ABI artifact this
 /// suppression should apply to.
 ///
-/// @param regexp the new regular expression string.
+/// @param regexp the new regular expression.
 void
-suppression_base::set_file_name_regex_str(const string& regexp)
-{priv_->file_name_regex_str_ = regexp;}
+suppression_base::set_file_name_regex(const regex_t_sptr& regexp)
+{priv_->file_name_regex_ = regexp;}
 
 /// Getter for the "file_name_regex" property of the current instance
 /// of @ref suppression_base.
 ///
-/// The "file_name_regex" property is a regular expression string that
+/// The "file_name_regex" property is a regular expression that
 /// designates the file name that contains the ABI artifacts this
 /// suppression should apply to.
 ///
-/// @return the regular expression string.
-const string&
-suppression_base::get_file_name_regex_str() const
-{return priv_->file_name_regex_str_;}
+/// @return the regular expression.
+const regex_t_sptr&
+suppression_base::get_file_name_regex() const
+{return priv_->file_name_regex_;}
 
 /// Setter for the "file_name_not_regex" property of the current
 /// instance of @ref suppression_base.
 ///
 /// The current suppression specification should apply to ABI
 /// artifacts of a file which name does *NOT* match the regular
-/// expression string designated by the "file_name_not_regex"
-/// property.
+/// expression designated by the "file_name_not_regex" property.
 ///
-/// @param regexp the new regular expression string.
+/// @param regexp the new regular expression.
 void
-suppression_base::set_file_name_not_regex_str(const string& regexp)
-{priv_->file_name_not_regex_str_ = regexp;}
+suppression_base::set_file_name_not_regex(const regex_t_sptr& regexp)
+{priv_->file_name_not_regex_ = regexp;}
 
 /// Getter for the "file_name_not_regex" property of the current
 /// instance of @ref suppression_base.
 ///
 /// The current suppression specification should apply to ABI
 /// artifacts of a file which name does *NOT* match the regular
-/// expression string designated by the "file_name_not_regex"
-/// property.
+/// expression designated by the "file_name_not_regex" property.
 ///
-/// @return the regular expression string.
-const string&
-suppression_base::get_file_name_not_regex_str() const
-{return priv_->file_name_not_regex_str_;}
+/// @return the regular expression.
+const regex_t_sptr&
+suppression_base::get_file_name_not_regex() const
+{return priv_->file_name_not_regex_;}
 
 /// Test if the current suppression has a property related to file
 /// name.
@@ -193,59 +191,56 @@  suppression_base::get_file_name_not_regex_str() const
 bool
 suppression_base::has_file_name_related_property() const
 {
-  return (!(get_file_name_regex_str().empty()
-	    && get_file_name_not_regex_str().empty()));
+  return get_file_name_regex() || get_file_name_not_regex();
 }
 
-/// Setter of the "soname_regex_str property of the current instance
+/// Setter of the "soname_regex" property of the current instance
 /// of @ref suppression_base.
 ///
-/// The "soname_regex_str" is a regular expression string that
-/// designates the soname of the shared library that contains the ABI
-/// artifacts this suppression should apply to.
+/// The "soname_regex" is a regular expression that designates the
+/// soname of the shared library that contains the ABI artifacts this
+/// suppression should apply to.
 ///
-/// @param regexp the new regular expression string.
+/// @param regexp the new regular expression.
 void
-suppression_base::set_soname_regex_str(const string& regexp)
-{priv_->soname_regex_str_ = regexp;}
+suppression_base::set_soname_regex(const regex_t_sptr& regexp)
+{priv_->soname_regex_ = regexp;}
 
-/// Getter of the "soname_regex_str property of the current instance
+/// Getter of the "soname_regex" property of the current instance
 /// of @ref suppression_base.
 ///
-/// The "soname_regex_str" is a regular expression string that
-/// designates the soname of the shared library that contains the ABI
-/// artifacts this suppression should apply to.
+/// The "soname_regex" is a regular expression that designates the
+/// soname of the shared library that contains the ABI artifacts this
+/// suppression should apply to.
 ///
-/// @return the regular expression string.
-const string&
-suppression_base::get_soname_regex_str() const
-{return priv_->soname_regex_str_;}
+/// @return the regular expression.
+const regex_t_sptr&
+suppression_base::get_soname_regex() const
+{return priv_->soname_regex_;}
 
-/// Setter of the "soname_not_regex_str property of the current
+/// Setter of the "soname_not_regex" property of the current
 /// instance of @ref suppression_base.
 ///
 /// The current suppression specification should apply to ABI
 /// artifacts of a shared library which SONAME does *NOT* match the
-/// regular expression string designated by the "soname_not_regex"
-/// property.
+/// regular expression designated by the "soname_not_regex" property.
 ///
-/// @param regexp the new regular expression string.
+/// @param regexp the new regular expression.
 void
-suppression_base::set_soname_not_regex_str(const string& regexp)
-{priv_->soname_not_regex_str_ = regexp;}
+suppression_base::set_soname_not_regex(const regex_t_sptr& regexp)
+{priv_->soname_not_regex_ = regexp;}
 
-/// Getter of the "soname_not_regex_str property of the current
+/// Getter of the "soname_not_regex" property of the current
 /// instance of @ref suppression_base.
 ///
 /// The current suppression specification should apply to ABI
 /// artifacts of a shared library which SONAME does *NOT* match the
-/// regular expression string designated by the "soname_not_regex"
-/// property.
+/// regular expression designated by the "soname_not_regex" property.
 ///
-/// @return the regular expression string.
-const string&
-suppression_base::get_soname_not_regex_str() const
-{return priv_->soname_not_regex_str_;}
+/// @return the regular expression.
+const regex_t_sptr&
+suppression_base::get_soname_not_regex() const
+{return priv_->soname_not_regex_;}
 
 /// Test if the current suppression has a property related to SONAMEs.
 ///
@@ -254,8 +249,7 @@  suppression_base::get_soname_not_regex_str() const
 bool
 suppression_base::has_soname_related_property() const
 {
-  return (!(get_soname_regex_str().empty()
-	    && get_soname_not_regex_str().empty()));
+  return get_soname_regex() || get_soname_not_regex();
 }
 
 /// Check if the SONAMEs of the two binaries being compared match the
@@ -397,8 +391,8 @@  read_suppressions(const string& file_path,
 /// form comment explaining what the suppression is about.
 ///
 /// @param type_name_regexp the regular expression describing the
-/// types about which diff reports should be suppressed.  If it's an
-/// empty string, the parameter is ignored.
+/// types about which diff reports should be suppressed.  If it's a
+/// null shared pointer, the parameter is ignored.
 ///
 /// @param type_name the name of the type about which diff reports
 /// should be suppressed.  If it's an empty string, the parameter is
@@ -408,7 +402,7 @@  read_suppressions(const string& file_path,
 /// should not necessarily be populated.  It usually is either one or
 /// the other that the user wants.
 type_suppression::type_suppression(const string& label,
-				   const string& type_name_regexp,
+				   const regex_t_sptr& type_name_regexp,
 				   const string& type_name)
   : suppression_base(label),
     priv_(new priv(type_name_regexp,
@@ -428,43 +422,43 @@  type_suppression::~type_suppression()
 /// This sets a regular expression that specifies the family of types
 /// about which diff reports should be suppressed.
 ///
-/// @param name_regex_str the new regular expression to set.
+/// @param name_regex the new regular expression to set.
 void
-type_suppression::set_type_name_regex_str(const string& name_regex_str)
-{priv_->type_name_regex_str_ = name_regex_str;}
+type_suppression::set_type_name_regex(const regex_t_sptr& name_regex)
+{priv_->type_name_regex_ = name_regex;}
 
 /// Getter for the "type_name_regex" property of the type suppression
 /// specification.
 ///
-/// This returns a regular expression string that specifies the family
+/// This returns a regular expression that specifies the family
 /// of types about which diff reports should be suppressed.
 ///
-/// @return the regular expression string.
-const string&
-type_suppression::get_type_name_regex_str() const
-{return priv_->type_name_regex_str_;}
+/// @return the regular expression.
+const regex_t_sptr&
+type_suppression::get_type_name_regex() const
+{return priv_->type_name_regex_;}
 
-/// Setter for the "type_name_not_regex_str" property of the type
+/// Setter for the "type_name_not_regex" property of the type
 /// suppression specification.
 ///
-/// This returns a regular expression string that specifies the family
+/// This sets a regular expression that specifies the family
 /// of types that should be kept after suppression.
 ///
 /// @param r the new regexp string.
 void
-type_suppression::set_type_name_not_regex_str(const string& r)
-{priv_->set_type_name_not_regex_str(r);}
+type_suppression::set_type_name_not_regex(const regex_t_sptr& r)
+{priv_->set_type_name_not_regex(r);}
 
-/// Getter for the "type_name_not_regex_str" property of the type
+/// Getter for the "type_name_not_regex" property of the type
 /// suppression specification.
 ///
-/// This returns a regular expression string that specifies the family
+/// This returns a regular expression that specifies the family
 /// of types that should be kept after suppression.
 ///
 /// @return the new regexp string.
-const string&
-type_suppression::get_type_name_not_regex_str() const
-{return priv_->get_type_name_not_regex_str();}
+const regex_t_sptr&
+type_suppression::get_type_name_not_regex() const
+{return priv_->type_name_not_regex_;}
 
 /// Setter for the name of the type about which diff reports should be
 /// suppressed.
@@ -612,21 +606,21 @@  type_suppression::set_source_locations_to_keep
 (const unordered_set<string>& l)
 {priv_->source_locations_to_keep_ = l;}
 
-/// Getter of the regular expression string that designates the source
+/// Getter of the regular expression that designates the source
 /// location paths of types that should not be suppressed.
 ///
-/// @return the regular expression string.
-const string&
-type_suppression::get_source_location_to_keep_regex_str() const
-{return priv_->source_location_to_keep_regex_str_;}
+/// @return the regular expression.
+const regex_t_sptr&
+type_suppression::get_source_location_to_keep_regex() const
+{return priv_->source_location_to_keep_regex_;}
 
-/// Setter of the regular expression string that designates the source
+/// Setter of the regular expression that designates the source
 /// location paths of types that should not be suppressed.
 ///
 /// @param r the new regular expression.
 void
-type_suppression::set_source_location_to_keep_regex_str(const string& r)
-{priv_->source_location_to_keep_regex_str_ = r;}
+type_suppression::set_source_location_to_keep_regex(const regex_t_sptr& r)
+{priv_->source_location_to_keep_regex_ = r;}
 
 /// Getter of the vector of the changed enumerators that are supposed
 /// to be suppressed.  Note that this will be "valid" only if the type
@@ -1563,39 +1557,43 @@  read_type_suppression(const ini::config::section& section)
 
   ini::simple_property_sptr file_name_regex_prop =
     is_simple_property(section.find_property("file_name_regexp"));
-  string file_name_regex_str =
-    file_name_regex_prop ? file_name_regex_prop->get_value()->as_string() : "";
+  regex_t_sptr file_name_regex;
+  if (file_name_regex_prop)
+    file_name_regex =
+      regex::compile(file_name_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr file_name_not_regex_prop =
     is_simple_property(section.find_property("file_name_not_regexp"));
-  string file_name_not_regex_str =
-    file_name_not_regex_prop
-    ? file_name_not_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr file_name_not_regex;
+  if (file_name_not_regex_prop)
+    file_name_not_regex =
+      regex::compile(file_name_not_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr soname_regex_prop =
     is_simple_property(section.find_property("soname_regexp"));
-  string soname_regex_str =
-    soname_regex_prop ? soname_regex_prop->get_value()->as_string() : "";
+  regex_t_sptr soname_regex;
+  if (soname_regex_prop)
+    soname_regex = regex::compile(soname_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr soname_not_regex_prop =
     is_simple_property(section.find_property("soname_not_regexp"));
-  string soname_not_regex_str =
-    soname_not_regex_prop
-    ? soname_not_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr soname_not_regex;
+  if (soname_not_regex_prop)
+    soname_not_regex =
+      regex::compile(soname_not_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr name_regex_prop =
     is_simple_property(section.find_property("name_regexp"));
-  string name_regex_str = name_regex_prop
-    ? name_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr name_regex;
+  if (name_regex_prop)
+    name_regex = regex::compile(name_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr name_not_regex_prop =
     is_simple_property(section.find_property("name_not_regexp"));
-  string name_not_regex_str = name_not_regex_prop
-    ? name_not_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr name_not_regex;
+  if (name_not_regex_prop)
+    name_not_regex =
+      regex::compile(name_not_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr name_prop =
     is_simple_property(section.find_property("name"));
@@ -1627,9 +1625,10 @@  read_type_suppression(const ini::config::section& section)
 
   ini::simple_property_sptr srcloc_not_regexp_prop =
     is_simple_property(section.find_property("source_location_not_regexp"));
-  string srcloc_not_regexp_str;
+  regex_t_sptr srcloc_not_regex;
   if (srcloc_not_regexp_prop)
-    srcloc_not_regexp_str = srcloc_not_regexp_prop->get_value()->as_string();
+    srcloc_not_regex =
+      regex::compile(srcloc_not_regexp_prop->get_value()->as_string());
 
   bool consider_type_kind = false;
   type_suppression::type_kind type_kind = type_suppression::UNKNOWN_TYPE_KIND;
@@ -1836,7 +1835,7 @@  read_type_suppression(const ini::config::section& section)
 	changed_enumerator_names.push_back(p->get_value()->as_string());
     }
 
-  result.reset(new type_suppression(label_str, name_regex_str, name_str));
+  result.reset(new type_suppression(label_str, name_regex, name_str));
 
   if (consider_type_kind)
     {
@@ -1853,31 +1852,31 @@  read_type_suppression(const ini::config::section& section)
   if (consider_data_member_insertion)
     result->set_data_member_insertion_ranges(insert_ranges);
 
-  if (!name_not_regex_str.empty())
-    result->set_type_name_not_regex_str(name_not_regex_str);
+  if (name_not_regex)
+    result->set_type_name_not_regex(name_not_regex);
 
-  if (!file_name_regex_str.empty())
-    result->set_file_name_regex_str(file_name_regex_str);
+  if (file_name_regex)
+    result->set_file_name_regex(file_name_regex);
 
-  if (!file_name_not_regex_str.empty())
-    result->set_file_name_not_regex_str(file_name_not_regex_str);
+  if (file_name_not_regex)
+    result->set_file_name_not_regex(file_name_not_regex);
 
-  if (!soname_regex_str.empty())
-    result->set_soname_regex_str(soname_regex_str);
+  if (soname_regex)
+    result->set_soname_regex(soname_regex);
 
-  if (!soname_not_regex_str.empty())
-    result->set_soname_not_regex_str(soname_not_regex_str);
+  if (soname_not_regex)
+    result->set_soname_not_regex(soname_not_regex);
 
   if (!srcloc_not_in.empty())
     result->set_source_locations_to_keep(srcloc_not_in);
 
-  if (!srcloc_not_regexp_str.empty())
-    result->set_source_location_to_keep_regex_str(srcloc_not_regexp_str);
+  if (srcloc_not_regex)
+    result->set_source_location_to_keep_regex(srcloc_not_regex);
 
   if ((drop_artifact_str == "yes" || drop_artifact_str == "true")
-      && ((!name_regex_str.empty()
+      && ((name_regex
 	   || !name_str.empty()
-	   || !srcloc_not_regexp_str.empty()
+	   || srcloc_not_regex
 	   || !srcloc_not_in.empty())))
     result->set_drops_artifact_from_ir(true);
 
@@ -1903,7 +1902,7 @@  read_type_suppression(const ini::config::section& section)
 /// account only if the parameter @p tn is empty.
 function_suppression::parameter_spec::parameter_spec(size_t i,
 						     const string& tn,
-						     const string& tn_regex)
+						     const regex_t_sptr& tn_regex)
   : priv_(new priv(i, tn, tn_regex))
 {}
 
@@ -1948,9 +1947,9 @@  function_suppression::parameter_spec::set_parameter_type_name(const string& tn)
 /// empty.
 ///
 /// @return the regular expression or the parameter type name.
-const string&
-function_suppression::parameter_spec::get_parameter_type_name_regex_str() const
-{return priv_->type_name_regex_str_;}
+const regex_t_sptr&
+function_suppression::parameter_spec::get_parameter_type_name_regex() const
+{return priv_->type_name_regex_;}
 
 /// Setter for the regular expression that defines a set of type names
 /// for the parameter designated by this specification.
@@ -1960,12 +1959,12 @@  function_suppression::parameter_spec::get_parameter_type_name_regex_str() const
 /// function_suppression::parameter_spec::get_parameter_type_name() is
 /// empty.
 ///
-/// @param type_name_regex_str the new type name regular expression to
+/// @param type_name_regex the new type name regular expression to
 /// set.
 void
-function_suppression::parameter_spec::set_parameter_type_name_regex_str
-(const string& type_name_regex_str)
-{priv_->type_name_regex_str_ = type_name_regex_str;}
+function_suppression::parameter_spec::set_parameter_type_name_regex
+(const regex_t_sptr& type_name_regex)
+{priv_->type_name_regex_ = type_name_regex;}
 
 /// Default constructor for the @ref function_suppression type.
 ///
@@ -2033,14 +2032,14 @@  function_suppression::function_suppression()
 /// case it's ignored at evaluation time.
 function_suppression::function_suppression(const string&		label,
 					   const string&		name,
-					   const string&		nr,
+					   const regex_t_sptr&		nr,
 					   const string&		ret_tn,
-					   const string&		ret_tr,
+					   const regex_t_sptr&		ret_tr,
 					   parameter_specs_type&	ps,
 					   const string&		sym_n,
-					   const string&		sym_nr,
+					   const regex_t_sptr&		sym_nr,
 					   const string&		sym_v,
-					   const string&		sym_vr)
+					   const regex_t_sptr&		sym_vr)
   : suppression_base(label),
     priv_(new priv(name, nr, ret_tn, ret_tr, ps,
 		   sym_n, sym_nr, sym_v, sym_vr))
@@ -2108,9 +2107,9 @@  function_suppression::set_name(const string& n)
 ///
 /// @return the regular expression for the possible names of the
 /// function(s).
-const string&
-function_suppression::get_name_regex_str() const
-{return priv_->name_regex_str_;}
+const regex_t_sptr&
+function_suppression::get_name_regex() const
+{return priv_->name_regex_;}
 
 /// Setter for a regular expression for a family of names of functions
 /// the user wants the current specification to designate.
@@ -2118,8 +2117,8 @@  function_suppression::get_name_regex_str() const
 /// @param r the new the regular expression for the possible names of
 /// the function(s).
 void
-function_suppression::set_name_regex_str(const string& r)
-{priv_->name_regex_str_ = r;}
+function_suppression::set_name_regex(const regex_t_sptr& r)
+{priv_->name_regex_ = r;}
 
 /// Getter for a regular expression of a family of names of functions
 /// the user wants the current specification to designate the negation
@@ -2127,9 +2126,9 @@  function_suppression::set_name_regex_str(const string& r)
 ///
 /// @return the regular expression for the possible names of the
 /// function(s).
-const string&
-function_suppression::get_name_not_regex_str() const
-{return priv_->name_not_regex_str_;}
+const regex_t_sptr&
+function_suppression::get_name_not_regex() const
+{return priv_->name_not_regex_;}
 
 /// Setter for a regular expression for a family of names of functions
 /// the user wants the current specification to designate the negation
@@ -2138,8 +2137,8 @@  function_suppression::get_name_not_regex_str() const
 /// @param r the new the regular expression for the possible names of
 /// the function(s).
 void
-function_suppression::set_name_not_regex_str(const string& r)
-{priv_->name_not_regex_str_ = r;}
+function_suppression::set_name_not_regex(const regex_t_sptr& r)
+{priv_->name_not_regex_ = r;}
 
 /// Getter for the name of the return type of the function the user
 /// wants this specification to designate.  This property might be
@@ -2171,9 +2170,9 @@  function_suppression::set_return_type_name(const string& tr)
 ///
 /// @return the regular expression for the possible names of the
 /// return types of the function(s).
-const string&
-function_suppression::get_return_type_regex_str() const
-{return priv_->return_type_regex_str_;}
+const regex_t_sptr&
+function_suppression::get_return_type_regex() const
+{return priv_->return_type_regex_;}
 
 /// Setter for a regular expression for a family of return type names
 /// for functions the user wants the current specification to
@@ -2188,8 +2187,8 @@  function_suppression::get_return_type_regex_str() const
 /// @param r the new regular expression for the possible names of the
 /// return types of the function(s) to set.
 void
-function_suppression::set_return_type_regex_str(const string& r)
-{priv_->return_type_regex_str_ = r;}
+function_suppression::set_return_type_regex(const regex_t_sptr& r)
+{priv_->return_type_regex_ = r;}
 
 /// Getter for a vector of parameter specifications to specify
 /// properties of the parameters of the functions the user wants this
@@ -2257,9 +2256,9 @@  function_suppression::set_symbol_name(const string& n)
 ///
 /// @return the regular expression for a family of names of symbols of
 /// functions to designate.
-const string&
-function_suppression::get_symbol_name_regex_str() const
-{return priv_->symbol_name_regex_str_;}
+const regex_t_sptr&
+function_suppression::get_symbol_name_regex() const
+{return priv_->symbol_name_regex_;}
 
 /// Setter for a regular expression for a family of names of symbols
 /// of functions the user wants this specification to designate.
@@ -2274,8 +2273,8 @@  function_suppression::get_symbol_name_regex_str() const
 /// @param r the new regular expression for a family of names of
 /// symbols of functions to set.
 void
-function_suppression::set_symbol_name_regex_str(const string& r)
-{priv_->symbol_name_regex_str_ = r;}
+function_suppression::set_symbol_name_regex(const regex_t_sptr& r)
+{priv_->symbol_name_regex_ = r;}
 
 /// Getter for a regular expression for a family of names of symbols
 /// of functions the user wants this specification to designate.
@@ -2290,11 +2289,11 @@  function_suppression::set_symbol_name_regex_str(const string& r)
 /// This property might be empty, in which case it's ignored at
 /// evaluation time.
 ///
-/// @return the regular expression string for a family of names of
+/// @return the regular expression for a family of names of
 /// symbols that is to be *NOT* suppressed by this suppression specification.
-const string&
-function_suppression::get_symbol_name_not_regex_str() const
-{return priv_->symbol_name_not_regex_str_;}
+const regex_t_sptr&
+function_suppression::get_symbol_name_not_regex() const
+{return priv_->symbol_name_not_regex_;}
 
 /// Setter for a regular expression for a family of names of symbols
 /// of functions the user wants this specification to designate.
@@ -2309,12 +2308,12 @@  function_suppression::get_symbol_name_not_regex_str() const
 /// This property might be empty, in which case it's ignored at
 /// evaluation time.
 ///
-/// @param the new regular expression string for a family of names of
+/// @param the new regular expression for a family of names of
 /// symbols that is to be *NOT* suppressed by this suppression
 /// specification.
 void
-function_suppression::set_symbol_name_not_regex_str(const string& r)
-{priv_->symbol_name_not_regex_str_ = r;}
+function_suppression::set_symbol_name_not_regex(const regex_t_sptr& r)
+{priv_->symbol_name_not_regex_ = r;}
 
 /// Getter for the name of the version of the symbol of the function
 /// the user wants this specification to designate.
@@ -2349,9 +2348,9 @@  function_suppression::set_symbol_version(const string& v)
 ///
 /// @return the regular expression for the versions of symbols of
 /// functions to designate.
-const string&
-function_suppression::get_symbol_version_regex_str() const
-{return priv_->symbol_version_regex_str_;}
+const regex_t_sptr&
+function_suppression::get_symbol_version_regex() const
+{return priv_->symbol_version_regex_;}
 
 /// Setter for a regular expression for a family of versions of
 /// symbols of functions the user wants the current specification to
@@ -2365,8 +2364,8 @@  function_suppression::get_symbol_version_regex_str() const
 /// @param the new regular expression for the versions of symbols of
 /// functions to designate.
 void
-function_suppression::set_symbol_version_regex_str(const string& r)
-{priv_->symbol_version_regex_str_ = r;}
+function_suppression::set_symbol_version_regex(const regex_t_sptr& r)
+{priv_->symbol_version_regex_ = r;}
 
 /// Getter for the "allow_other_aliases" property of the function
 /// suppression specification.
@@ -2769,7 +2768,7 @@  function_suppression::suppresses_function_symbol(const elf_symbol* sym,
       if (sym_name != get_symbol_name())
 	return false;
     }
-  else if (!get_symbol_name_regex_str().empty())
+  else if (get_symbol_name_regex())
     {
       const regex_t_sptr symbol_name_regex = priv_->get_symbol_name_regex();
       if (symbol_name_regex && !regex::match(symbol_name_regex, sym_name))
@@ -2784,7 +2783,7 @@  function_suppression::suppresses_function_symbol(const elf_symbol* sym,
       if (sym_version != get_symbol_version())
 	return false;
     }
-  else if (!get_symbol_version_regex_str().empty())
+  else if (get_symbol_version_regex())
     {
       const regex_t_sptr symbol_version_regex =
 	priv_->get_symbol_version_regex();
@@ -3090,10 +3089,10 @@  read_parameter_spec_from_string(const string& str)
 
   if (!index_str.empty() || !type_name.empty())
     {
-      std::string type_name_regex;
+      regex_t_sptr type_name_regex;
       if (is_regex)
 	{
-	  type_name_regex = type_name;
+	  type_name_regex = regex::compile(type_name);
 	  type_name.clear();
 	}
       function_suppression::parameter_spec* p =
@@ -3143,27 +3142,30 @@  read_function_suppression(const ini::config::section& section)
 
   ini::simple_property_sptr file_name_regex_prop =
     is_simple_property(section.find_property("file_name_regexp"));
-  string file_name_regex_str =
-    file_name_regex_prop ? file_name_regex_prop->get_value()->as_string() : "";
+  regex_t_sptr file_name_regex;
+  if (file_name_regex_prop)
+    file_name_regex =
+      regex::compile(file_name_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr file_name_not_regex_prop =
     is_simple_property(section.find_property("file_name_not_regexp"));
-  string file_name_not_regex_str =
-    file_name_not_regex_prop
-    ? file_name_not_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr file_name_not_regex;
+  if (file_name_not_regex_prop)
+    file_name_not_regex =
+      regex::compile(file_name_not_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr soname_regex_prop =
     is_simple_property(section.find_property("soname_regexp"));
-  string soname_regex_str =
-    soname_regex_prop ? soname_regex_prop->get_value()->as_string() : "";
+  regex_t_sptr soname_regex;
+  if (soname_regex_prop)
+    soname_regex = regex::compile(soname_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr soname_not_regex_prop =
     is_simple_property(section.find_property("soname_not_regexp"));
-  string soname_not_regex_str =
-    soname_not_regex_prop
-    ? soname_not_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr soname_not_regex;
+  if (soname_not_regex_prop)
+    soname_not_regex =
+      regex::compile(soname_not_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr name_prop =
     is_simple_property(section.find_property("name"));
@@ -3173,15 +3175,16 @@  read_function_suppression(const ini::config::section& section)
 
   ini::simple_property_sptr name_regex_prop =
     is_simple_property(section.find_property("name_regexp"));
-  string name_regex_str = name_regex_prop
-    ? name_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr name_regex;
+  if (name_regex_prop)
+    name_regex = regex::compile(name_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr name_not_regex_prop =
     is_simple_property(section.find_property("name_not_regexp"));
-  string name_not_regex_str = name_not_regex_prop
-    ? name_not_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr name_not_regex;
+  if (name_not_regex_prop)
+    name_not_regex =
+      regex::compile(name_not_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr return_type_name_prop =
     is_simple_property(section.find_property("return_type_name"));
@@ -3191,9 +3194,10 @@  read_function_suppression(const ini::config::section& section)
 
   ini::simple_property_sptr return_type_regex_prop =
     is_simple_property(section.find_property("return_type_regexp"));
-  string return_type_regex_str = return_type_regex_prop
-    ? return_type_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr return_type_regex;
+  if (return_type_regex_prop)
+    return_type_regex =
+      regex::compile(return_type_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr sym_name_prop =
     is_simple_property(section.find_property("symbol_name"));
@@ -3203,15 +3207,17 @@  read_function_suppression(const ini::config::section& section)
 
   ini::simple_property_sptr sym_name_regex_prop =
     is_simple_property(section.find_property("symbol_name_regexp"));
-  string sym_name_regex_str = sym_name_regex_prop
-    ? sym_name_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr sym_name_regex;
+  if (sym_name_regex_prop)
+    sym_name_regex =
+      regex::compile(sym_name_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr sym_name_not_regex_prop =
     is_simple_property(section.find_property("symbol_name_not_regexp"));
-  string sym_name_not_regex_str = sym_name_not_regex_prop
-    ? sym_name_not_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr sym_name_not_regex;
+  if (sym_name_not_regex_prop)
+    sym_name_not_regex =
+      regex::compile(sym_name_not_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr sym_ver_prop =
     is_simple_property(section.find_property("symbol_version"));
@@ -3221,9 +3227,10 @@  read_function_suppression(const ini::config::section& section)
 
   ini::simple_property_sptr sym_ver_regex_prop =
     is_simple_property(section.find_property("symbol_version_regexp"));
-  string sym_ver_regex_str = sym_ver_regex_prop
-    ? sym_ver_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr sym_ver_regex;
+  if (sym_ver_regex_prop)
+    sym_ver_regex =
+      regex::compile(sym_ver_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr allow_other_aliases_prop =
     is_simple_property(section.find_property("allow_other_aliases"));
@@ -3248,22 +3255,22 @@  read_function_suppression(const ini::config::section& section)
 
   result.reset(new function_suppression(label_str,
 					name,
-					name_regex_str,
+					name_regex,
 					return_type_name,
-					return_type_regex_str,
+					return_type_regex,
 					parms,
 					sym_name,
-					sym_name_regex_str,
+					sym_name_regex,
 					sym_version,
-					sym_ver_regex_str));
+					sym_ver_regex));
 
   if ((drop_artifact_str == "yes" || drop_artifact_str == "true")
       && (!name.empty()
-	  || !name_regex_str.empty()
-	  || !name_not_regex_str.empty()
+	  || name_regex
+	  || name_not_regex
 	  || !sym_name.empty()
-	  || !sym_name_regex_str.empty()
-	  || !sym_name_not_regex_str.empty()))
+	  || sym_name_regex
+	  || sym_name_not_regex))
     result->set_drops_artifact_from_ir(true);
 
   if (!change_kind_str.empty())
@@ -3274,23 +3281,23 @@  read_function_suppression(const ini::config::section& section)
     result->set_allow_other_aliases(allow_other_aliases == "yes"
 				    || allow_other_aliases == "true");
 
-  if (!name_not_regex_str.empty())
-    result->set_name_not_regex_str(name_not_regex_str);
+  if (name_not_regex)
+    result->set_name_not_regex(name_not_regex);
 
-  if (!sym_name_not_regex_str.empty())
-    result->set_symbol_name_not_regex_str(sym_name_not_regex_str);
+  if (sym_name_not_regex)
+    result->set_symbol_name_not_regex(sym_name_not_regex);
 
-  if (!file_name_regex_str.empty())
-    result->set_file_name_regex_str(file_name_regex_str);
+  if (file_name_regex)
+    result->set_file_name_regex(file_name_regex);
 
-  if (!file_name_not_regex_str.empty())
-    result->set_file_name_not_regex_str(file_name_not_regex_str);
+  if (file_name_not_regex)
+    result->set_file_name_not_regex(file_name_not_regex);
 
-  if (!soname_regex_str.empty())
-    result->set_soname_regex_str(soname_regex_str);
+  if (soname_regex)
+    result->set_soname_regex(soname_regex);
 
-  if (!soname_not_regex_str.empty())
-    result->set_soname_not_regex_str(soname_not_regex_str);
+  if (soname_not_regex)
+    result->set_soname_not_regex(soname_not_regex);
 
   return result;
 }
@@ -3310,7 +3317,7 @@  read_function_suppression(const ini::config::section& section)
 /// specification to designate.  This parameter might be empty, in
 /// which case it's ignored at evaluation time.
 ///
-/// @param name_regex_str if @p name is empty, this parameter is a
+/// @param name_regex if @p name is empty, this parameter is a
 /// regular expression for a family of names of variables the user
 /// wants the current specification to designate.  If @p name is not
 /// empty, then this parameter is ignored at evaluation time.  This
@@ -3344,7 +3351,7 @@  read_function_suppression(const ini::config::section& section)
 /// wants the current specification to designate.  This parameter
 /// might be empty, in which case it's ignored at evaluation time.
 ///
-/// @param type_name_regex_str if @p type_name is empty, then this
+/// @param type_name_regex if @p type_name is empty, then this
 /// parameter is a regular expression for a family of type names of
 /// variables the user wants the current specification to designate.
 /// If @p type_name is not empty, then this parameter is ignored at
@@ -3352,18 +3359,18 @@  read_function_suppression(const ini::config::section& section)
 /// ignored at evaluation time.
 variable_suppression::variable_suppression(const string& label,
 					   const string& name,
-					   const string& name_regex_str,
+					   const regex_t_sptr& name_regex,
 					   const string& symbol_name,
-					   const string& symbol_name_regex_str,
+					   const regex_t_sptr& symbol_name_regex,
 					   const string& symbol_version,
-					   const string& symbol_version_regex,
+					   const regex_t_sptr& symbol_version_regex,
 					   const string& type_name,
-					   const string& type_name_regex_str)
+					   const regex_t_sptr& type_name_regex)
   : suppression_base(label),
-    priv_(new priv(name, name_regex_str,
-		   symbol_name, symbol_name_regex_str,
+    priv_(new priv(name, name_regex,
+		   symbol_name, symbol_name_regex,
 		   symbol_version, symbol_version_regex,
-		   type_name, type_name_regex_str))
+		   type_name, type_name_regex))
 {}
 
 /// Virtual destructor for the @erf variable_suppression type.
@@ -3433,9 +3440,9 @@  variable_suppression::set_name(const string& n)
 /// which case it's ignored at evaluation time.
 ///
 /// @return the regular expression for the variable name.
-const string&
-variable_suppression::get_name_regex_str() const
-{return priv_->name_regex_str_;}
+const regex_t_sptr&
+variable_suppression::get_name_regex() const
+{return priv_->name_regex_;}
 
 /// Setter for the regular expression for a family of names of
 /// variables the user wants the current specification to designate.
@@ -3446,22 +3453,22 @@  variable_suppression::get_name_regex_str() const
 ///
 /// @param r the new regular expression for the variable name.
 void
-variable_suppression::set_name_regex_str(const string& r)
-{priv_->name_regex_str_ = r;}
+variable_suppression::set_name_regex(const regex_t_sptr& r)
+{priv_->name_regex_ = r;}
 
 /// Getter for the "name_not_regexp" property of the specification.
 ///
 /// @return the value of the "name_not_regexp" property.
-const string&
-variable_suppression::get_name_not_regex_str() const
-{return priv_->name_not_regex_str_;}
+const regex_t_sptr&
+variable_suppression::get_name_not_regex() const
+{return priv_->name_not_regex_;}
 
 /// Setter for the "name_not_regexp" property of the specification.
 ///
 /// @param r the new value of the "name_not_regexp" property.
 void
-variable_suppression::set_name_not_regex_str(const string& r)
-{priv_->name_not_regex_str_ = r;}
+variable_suppression::set_name_not_regex(const regex_t_sptr& r)
+{priv_->name_not_regex_ = r;}
 
 /// Getter for the name of the symbol of the variable the user wants
 /// the current specification to designate.
@@ -3494,9 +3501,9 @@  variable_suppression::set_symbol_name(const string& n)
 /// empty.
 ///
 /// @return the regular expression for a symbol name of the variable.
-const string&
-variable_suppression::get_symbol_name_regex_str() const
-{return priv_->symbol_name_regex_str_;}
+const regex_t_sptr&
+variable_suppression::get_symbol_name_regex() const
+{return priv_->symbol_name_regex_;}
 
 /// Setter of the regular expression for a family of symbol names of
 /// the variables this specification is about to designate.
@@ -3508,8 +3515,8 @@  variable_suppression::get_symbol_name_regex_str() const
 ///
 /// @param r the regular expression for a symbol name of the variable.
 void
-variable_suppression::set_symbol_name_regex_str(const string& r)
-{priv_->symbol_name_regex_str_ = r;}
+variable_suppression::set_symbol_name_regex(const regex_t_sptr& r)
+{priv_->symbol_name_regex_ = r;}
 
 /// Getter for a regular expression for a family of names of symbols
 /// of variables the user wants this specification to designate.
@@ -3524,11 +3531,11 @@  variable_suppression::set_symbol_name_regex_str(const string& r)
 /// This property might be empty, in which case it's ignored at
 /// evaluation time.
 ///
-/// @return the regular expression string for a family of names of
+/// @return the regular expression for a family of names of
 /// symbols that is to be *NOT* suppressed by this suppression specification.
-const string&
-variable_suppression::get_symbol_name_not_regex_str() const
-{return priv_->symbol_name_not_regex_str_;}
+const regex_t_sptr&
+variable_suppression::get_symbol_name_not_regex() const
+{return priv_->symbol_name_not_regex_;}
 
 /// Setter for a regular expression for a family of names of symbols
 /// of variables the user wants this specification to designate.
@@ -3543,12 +3550,12 @@  variable_suppression::get_symbol_name_not_regex_str() const
 /// This property might be empty, in which case it's ignored at
 /// evaluation time.
 ///
-/// @param the new regular expression string for a family of names of
+/// @param the new regular expression for a family of names of
 /// symbols that is to be *NOT* suppressed by this suppression
 /// specification.
 void
-variable_suppression::set_symbol_name_not_regex_str(const string& r)
-{priv_->symbol_name_not_regex_str_ = r;}
+variable_suppression::set_symbol_name_not_regex(const regex_t_sptr& r)
+{priv_->symbol_name_not_regex_ = r;}
 
 /// Getter for the version of the symbol of the variable the user
 /// wants the current specification to designate.  This property might
@@ -3576,9 +3583,9 @@  variable_suppression::set_symbol_version(const string& v)
 ///
 /// @return the regular expression of the symbol version of the
 /// variable.
-const string&
-variable_suppression::get_symbol_version_regex_str() const
-{return priv_->symbol_version_regex_str_;}
+const regex_t_sptr&
+variable_suppression::get_symbol_version_regex() const
+{return priv_->symbol_version_regex_;}
 
 /// Setter of the regular expression for a family of versions of
 /// symbol for the variables the user wants the current specification
@@ -3589,8 +3596,8 @@  variable_suppression::get_symbol_version_regex_str() const
 /// @param v the new regular expression of the symbol version of the
 /// variable.
 void
-variable_suppression::set_symbol_version_regex_str(const string& r)
-{priv_->symbol_version_regex_str_ = r;}
+variable_suppression::set_symbol_version_regex(const regex_t_sptr& r)
+{priv_->symbol_version_regex_ = r;}
 
 /// Getter for the name of the type of the variable the user wants the
 /// current specification to designate.
@@ -3623,9 +3630,9 @@  variable_suppression::set_type_name(const string& n)
 /// empty, in which case it's ignored at evaluation time.
 ///
 /// @return the regular expression of the variable type name.
-const string&
-variable_suppression::get_type_name_regex_str() const
-{return priv_->type_name_regex_str_;}
+const regex_t_sptr&
+variable_suppression::get_type_name_regex() const
+{return priv_->type_name_regex_;}
 
 /// Setter for the regular expression for a family of type names of
 /// variables the user wants the current specification to designate.
@@ -3637,8 +3644,8 @@  variable_suppression::get_type_name_regex_str() const
 ///
 /// @param r the regular expression of the variable type name.
 void
-variable_suppression::set_type_name_regex_str(const string& r)
-{priv_->type_name_regex_str_ = r;}
+variable_suppression::set_type_name_regex(const regex_t_sptr& r)
+{priv_->type_name_regex_ = r;}
 
 /// Evaluate this suppression specification on a given diff node and
 /// say if the diff node should be suppressed or not.
@@ -3867,7 +3874,7 @@  variable_suppression::suppresses_variable_symbol(const elf_symbol* sym,
       if (get_symbol_name() != sym_name)
 	return false;
     }
-  else if (!get_symbol_name_regex_str().empty())
+  else if (get_symbol_name_regex())
     {
       const regex_t_sptr sym_name_regex = priv_->get_symbol_name_regex();
       if (sym_name_regex && !regex::match(sym_name_regex, sym_name))
@@ -3883,7 +3890,7 @@  variable_suppression::suppresses_variable_symbol(const elf_symbol* sym,
       if (get_symbol_version() != sym_version)
 	return false;
     }
-  else if (!get_symbol_version_regex_str().empty())
+  else if (get_symbol_version_regex())
     {
       const regex_t_sptr symbol_version_regex =
 	priv_->get_symbol_version_regex();
@@ -4001,27 +4008,30 @@  read_variable_suppression(const ini::config::section& section)
 
   ini::simple_property_sptr file_name_regex_prop =
     is_simple_property(section.find_property("file_name_regexp"));
-  string file_name_regex_str =
-    file_name_regex_prop ? file_name_regex_prop->get_value()->as_string() : "";
+  regex_t_sptr file_name_regex;
+  if (file_name_regex_prop)
+    file_name_regex =
+      regex::compile(file_name_regex_prop->get_value()->as_string());
 
  ini::simple_property_sptr file_name_not_regex_prop =
-    is_simple_property(section.find_property("file_name_not_regexp"));
-  string file_name_not_regex_str =
-    file_name_not_regex_prop
-    ? file_name_not_regex_prop->get_value()->as_string()
-    : "";
+  is_simple_property(section.find_property("file_name_not_regexp"));
+ regex_t_sptr file_name_not_regex;
+ if (file_name_not_regex_prop)
+   file_name_not_regex =
+     regex::compile(file_name_not_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr soname_regex_prop =
     is_simple_property(section.find_property("soname_regexp"));
-  string soname_regex_str =
-    soname_regex_prop ? soname_regex_prop->get_value()->as_string() : "";
+  regex_t_sptr soname_regex;
+  if (soname_regex_prop)
+    soname_regex = regex::compile(soname_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr soname_not_regex_prop =
     is_simple_property(section.find_property("soname_not_regexp"));
-  string soname_not_regex_str =
-    soname_not_regex_prop
-    ? soname_not_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr soname_not_regex;
+  if (soname_not_regex_prop)
+    soname_not_regex =
+      regex::compile(soname_not_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr name_prop =
     is_simple_property(section.find_property("name"));
@@ -4031,15 +4041,16 @@  read_variable_suppression(const ini::config::section& section)
 
   ini::simple_property_sptr name_regex_prop =
     is_simple_property(section.find_property("name_regexp"));
-  string name_regex_str = (name_regex_prop
-			   ? name_regex_prop->get_value()->as_string()
-			   : "");
+  regex_t_sptr name_regex;
+  if (name_regex_prop)
+    name_regex = regex::compile(name_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr name_not_regex_prop =
     is_simple_property(section.find_property("name_not_regexp"));
-  string name_not_regex_str = name_not_regex_prop
-    ? name_not_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr name_not_regex;
+  if (name_not_regex_prop)
+    name_not_regex =
+      regex::compile(name_not_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr sym_name_prop =
     is_simple_property(section.find_property("symbol_name"));
@@ -4049,15 +4060,17 @@  read_variable_suppression(const ini::config::section& section)
 
   ini::simple_property_sptr sym_name_regex_prop =
     is_simple_property(section.find_property("symbol_name_regexp"));
-  string symbol_name_regex_str = sym_name_regex_prop
-    ? sym_name_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr symbol_name_regex;
+  if (sym_name_regex_prop)
+    symbol_name_regex =
+      regex::compile(sym_name_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr sym_name_not_regex_prop =
     is_simple_property(section.find_property("symbol_name_not_regexp"));
-  string symbol_name_not_regex_str = sym_name_not_regex_prop
-    ? sym_name_not_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr symbol_name_not_regex;
+  if (sym_name_not_regex_prop)
+    symbol_name_not_regex =
+      regex::compile(sym_name_not_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr sym_version_prop =
     is_simple_property(section.find_property("symbol_version"));
@@ -4067,9 +4080,10 @@  read_variable_suppression(const ini::config::section& section)
 
   ini::simple_property_sptr sym_version_regex_prop =
     is_simple_property(section.find_property("symbol_version_regexp"));
-  string symbol_version_regex_str = sym_version_regex_prop
-    ? sym_version_regex_prop->get_value()->as_string()
-     : "";
+  regex_t_sptr symbol_version_regex;
+  if (sym_version_regex_prop)
+    symbol_version_regex =
+      regex::compile(sym_version_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr type_name_prop =
     is_simple_property(section.find_property("type_name"));
@@ -4079,50 +4093,51 @@  read_variable_suppression(const ini::config::section& section)
 
   ini::simple_property_sptr type_name_regex_prop =
     is_simple_property(section.find_property("type_name_regexp"));
-  string type_name_regex_str = type_name_regex_prop
-    ? type_name_regex_prop->get_value()->as_string()
-     : "";
+  regex_t_sptr type_name_regex;
+  if (type_name_regex_prop)
+    type_name_regex =
+      regex::compile(type_name_regex_prop->get_value()->as_string());
 
   result.reset(new variable_suppression(label_str,
 					name_str,
-					name_regex_str,
+					name_regex,
 					symbol_name,
-					symbol_name_regex_str,
+					symbol_name_regex,
 					symbol_version,
-					symbol_version_regex_str,
+					symbol_version_regex,
 					type_name_str,
-					type_name_regex_str));
+					type_name_regex));
 
   if ((drop_artifact_str == "yes" || drop_artifact_str == "true")
       && (!name_str.empty()
-	  || !name_regex_str.empty()
-	  || !name_not_regex_str.empty()
+	  || name_regex
+	  || name_not_regex
 	  || !symbol_name.empty()
-	  || !symbol_name_regex_str.empty()
-	  || !symbol_name_not_regex_str.empty()))
+	  || symbol_name_regex
+	  || symbol_name_not_regex))
     result->set_drops_artifact_from_ir(true);
 
-  if (!name_not_regex_str.empty())
-    result->set_name_not_regex_str(name_not_regex_str);
+  if (name_not_regex)
+    result->set_name_not_regex(name_not_regex);
 
-  if (!symbol_name_not_regex_str.empty())
-    result->set_symbol_name_not_regex_str(symbol_name_not_regex_str);
+  if (symbol_name_not_regex)
+    result->set_symbol_name_not_regex(symbol_name_not_regex);
 
   if (!change_kind_str.empty())
     result->set_change_kind
       (variable_suppression::parse_change_kind(change_kind_str));
 
-  if (!file_name_regex_str.empty())
-    result->set_file_name_regex_str(file_name_regex_str);
+  if (file_name_regex)
+    result->set_file_name_regex(file_name_regex);
 
-  if (!file_name_not_regex_str.empty())
-    result->set_file_name_not_regex_str(file_name_not_regex_str);
+  if (file_name_not_regex)
+    result->set_file_name_not_regex(file_name_not_regex);
 
-  if (!soname_regex_str.empty())
-    result->set_soname_regex_str(soname_regex_str);
+  if (soname_regex)
+    result->set_soname_regex(soname_regex);
 
-  if (!soname_not_regex_str.empty())
-    result->set_soname_not_regex_str(soname_not_regex_str);
+  if (soname_not_regex)
+    result->set_soname_not_regex(soname_not_regex);
 
   return result;
 }
@@ -4135,21 +4150,21 @@  read_variable_suppression(const ini::config::section& section)
 ///
 /// @param label the label of the suppression directive.
 ///
-/// @param fname_regex_str the regular expression string that
+/// @param fname_regex the regular expression that
 /// designates the file name that instances of @ref file_suppression
 /// should match.
 ///
-/// @param fname_not_regex_str the regular expression string that
+/// @param fname_not_regex the regular expression that
 /// designates the file name that instances of @ref file_suppression
 /// shoult *NOT* match.  In other words, this file_suppression should
 /// be activated if its file name does not match the regular
-/// expression @p fname_not_regex_str.
+/// expression @p fname_not_regex.
 file_suppression::file_suppression(const string& label,
-				   const string& fname_regex_str,
-				   const string& fname_not_regex_str)
+				   const regex_t_sptr& fname_regex,
+				   const regex_t_sptr& fname_not_regex)
   : suppression_base(label,
-		     fname_regex_str,
-		     fname_not_regex_str)
+		     fname_regex,
+		     fname_not_regex)
 {}
 
 /// Test if instances of this @ref file_suppression suppresses a
@@ -4229,41 +4244,44 @@  read_file_suppression(const ini::config::section& section)
 
   ini::simple_property_sptr file_name_regex_prop =
     is_simple_property(section.find_property("file_name_regexp"));
-  string file_name_regex_str =
-    file_name_regex_prop ? file_name_regex_prop->get_value()->as_string() : "";
+  regex_t_sptr file_name_regex;
+  if (file_name_regex_prop)
+    file_name_regex =
+      regex::compile(file_name_regex_prop->get_value()->as_string());
 
  ini::simple_property_sptr file_name_not_regex_prop =
     is_simple_property(section.find_property("file_name_not_regexp"));
-  string file_name_not_regex_str =
-    file_name_not_regex_prop
-    ? file_name_not_regex_prop->get_value()->as_string()
-    : "";
+ regex_t_sptr file_name_not_regex;
+ if (file_name_not_regex_prop)
+   file_name_not_regex =
+     regex::compile(file_name_not_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr soname_regex_prop =
     is_simple_property(section.find_property("soname_regexp"));
-  string soname_regex_str =
-    soname_regex_prop ? soname_regex_prop->get_value()->as_string() : "";
+  regex_t_sptr soname_regex;
+  if (soname_regex_prop)
+    soname_regex = regex::compile(soname_regex_prop->get_value()->as_string());
 
   ini::simple_property_sptr soname_not_regex_prop =
     is_simple_property(section.find_property("soname_not_regexp"));
-  string soname_not_regex_str =
-    soname_not_regex_prop
-    ? soname_not_regex_prop->get_value()->as_string()
-    : "";
+  regex_t_sptr soname_not_regex;
+  if (soname_not_regex_prop)
+    soname_not_regex =
+      regex::compile(soname_not_regex_prop->get_value()->as_string());
 
   result.reset(new file_suppression(label_str,
-				    file_name_regex_str,
-				    file_name_not_regex_str));
+				    file_name_regex,
+				    file_name_not_regex));
 
-  if (!soname_regex_str.empty())
+  if (soname_regex)
     {
-      result->set_soname_regex_str(soname_regex_str);
+      result->set_soname_regex(soname_regex);
       result->set_drops_artifact_from_ir(true);
     }
 
-  if (!soname_not_regex_str.empty())
+  if (soname_not_regex)
     {
-      result->set_soname_not_regex_str(soname_not_regex_str);
+      result->set_soname_not_regex(soname_not_regex);
       result->set_drops_artifact_from_ir(true);
     }
 
diff --git a/src/abg-tools-utils.cc b/src/abg-tools-utils.cc
index 11486a21..fe0de750 100644
--- a/src/abg-tools-utils.cc
+++ b/src/abg-tools-utils.cc
@@ -1810,13 +1810,15 @@  handle_file_entry(const string& file_path,
 {
   if (!suppr)
     {
-      suppr.reset(new type_suppression(get_private_types_suppr_spec_label(),
-				       /*type_name_regexp=*/"",
-				       /*type_name=*/""));
+      suppr.reset(
+	new type_suppression(get_private_types_suppr_spec_label(),
+			     /*type_name_regexp=*/regex::regex_t_sptr(),
+			     /*type_name=*/""));
 
       // Types that are defined in system headers are usually
       // OK to be considered as public types.
-      suppr->set_source_location_to_keep_regex_str("^/usr/include/");
+      regex::regex_t_sptr headers_regex = regex::compile("^/usr/include/");
+      suppr->set_source_location_to_keep_regex(headers_regex);
       suppr->set_is_artificial(true);
     }
 
@@ -2004,7 +2006,8 @@  gen_suppr_spec_from_kernel_abi_whitelists
 
       // Build a regular expression representing the union of all
       // the function and variable names expressed in the white list.
-      const std::string regex = regex::generate_from_strings(whitelisted_names);
+      regex::regex_t_sptr regex =
+	regex::compile(regex::generate_from_strings(whitelisted_names));
 
       // Build a suppression specification which *keeps* functions
       // whose ELF symbols match the regular expression contained
@@ -2013,7 +2016,7 @@  gen_suppr_spec_from_kernel_abi_whitelists
       // match this regexp.
       function_suppression_sptr fn_suppr(new function_suppression);
       fn_suppr->set_label("whitelist");
-      fn_suppr->set_symbol_name_not_regex_str(regex);
+      fn_suppr->set_symbol_name_not_regex(regex);
       fn_suppr->set_drops_artifact_from_ir(true);
       result.push_back(fn_suppr);
 
@@ -2024,7 +2027,7 @@  gen_suppr_spec_from_kernel_abi_whitelists
       // match this regexp.
       variable_suppression_sptr var_suppr(new variable_suppression);
       var_suppr->set_label("whitelist");
-      var_suppr->set_symbol_name_not_regex_str(regex);
+      var_suppr->set_symbol_name_not_regex(regex);
       var_suppr->set_drops_artifact_from_ir(true);
       result.push_back(var_suppr);
     }
diff --git a/tests/test-kmi-whitelist.cc b/tests/test-kmi-whitelist.cc
index bcc5adee..16cc1861 100644
--- a/tests/test-kmi-whitelist.cc
+++ b/tests/test-kmi-whitelist.cc
@@ -29,10 +29,14 @@ 
 #include "lib/catch.hpp"
 
 #include "abg-fwd.h"
-#include "abg-suppression.h"
+#include "abg-regex.h"
 #include "abg-tools-utils.h"
+#include "abg-suppression.h"
 #include "test-utils.h"
 
+using abigail::regex::regex_t_sptr;
+using abigail::regex::compile;
+using abigail::regex::match;
 using abigail::tools_utils::gen_suppr_spec_from_kernel_abi_whitelists;
 using abigail::suppr::suppression_sptr;
 using abigail::suppr::suppressions_type;
@@ -57,9 +61,30 @@  const static std::string whitelist_with_duplicate_entry
     = std::string(abigail::tests::get_src_dir())
       + "/tests/data/test-kmi-whitelist/whitelist-with-duplicate-entry";
 
+// These are strings, not regexes, we cannot exhaustively check all
+// strings, but we can do some sampling and match sure we haven't got
+// the regex logic completely wrong.
+static const char* const random_symbols[] =
+{
+  "",
+  ".*",
+  "^$",
+  "test_symbol",
+  "test-symbol",
+  "test symbol",
+  "Test Symbol",
+  "est_symbo",
+  ".*test_symbol.*",
+  "test_symbol ",
+  " test_symbol",
+  " test_symbol ",
+  "test_another_symbol",
+  "$test_another_symbol",
+};
+
 void
 test_suppressions_are_consistent(const suppressions_type& suppr,
-			    const std::string&	     expr)
+				 const std::string&	  expr)
 {
   REQUIRE(suppr.size() == 2);
 
@@ -74,11 +99,32 @@  test_suppressions_are_consistent(const suppressions_type& suppr,
   // same mode
   REQUIRE(left->get_drops_artifact_from_ir()
 	  == right->get_drops_artifact_from_ir());
-  // same regex
-  REQUIRE(left->get_symbol_name_not_regex_str()
-     == right->get_symbol_name_not_regex_str());
-  // regex as expected
-  REQUIRE(left->get_symbol_name_not_regex_str() == expr);
+
+  // these parts of the symbol name matching should be absent
+  REQUIRE(left->get_symbol_name().empty());
+  REQUIRE(!left->get_symbol_name_regex());
+  REQUIRE(right->get_symbol_name().empty());
+  REQUIRE(!right->get_symbol_name_regex());
+
+  regex_t_sptr left_regex = left->get_symbol_name_not_regex();
+  regex_t_sptr right_regex = right->get_symbol_name_not_regex();
+  regex_t_sptr check_regex = compile(expr);
+
+  // all regexes present (compiled)
+  REQUIRE(left_regex);
+  REQUIRE(right_regex);
+  REQUIRE(check_regex);
+
+  // all regexes match or do not match a random symbol
+  for (size_t i = 0; i < sizeof(random_symbols)/sizeof(random_symbols[0]); ++i)
+    {
+      const std::string symbol(random_symbols[i]);
+      bool left_matches = match(left_regex, symbol);
+      bool right_matches = match(right_regex, symbol);
+      bool check_matches = match(check_regex, symbol);
+      REQUIRE(left_matches == right_matches);
+      REQUIRE(left_matches == check_matches);
+    }
 }
 
 TEST_CASE("NoWhitelists", "[whitelists]")