[PATCH v4 10/15] Compile suppression regexes earlier.

Matthias Maennich maennich@google.com
Mon May 4 13:14:03 GMT 2020


On Mon, May 04, 2020 at 01:34:11PM +0100, Giuliano Procida wrote:
>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>

That is indeed a very nice simplification!
I read through the patch, a lot is mechanical replacements. Thus I hope
I did not miss anything, but this likely needs another pair of eyes to
look through.

(Some includes could be sorted.)

Reviewed-by: Matthias Maennich <maennich@google.com>

Cheers,
Matthias
>---
> 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(-)
>
>diff --git a/include/abg-suppression.h b/include/abg-suppression.h
>index 6383b932..8256f9b8 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 deb08269..c5f99c15 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 4014ff06..80ac1e9f 100644
>--- a/src/abg-suppression.cc
>+++ b/src/abg-suppression.cc
>@@ -67,17 +67,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))
> {
> }
>
>@@ -139,52 +139,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.
>@@ -194,59 +192,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.
> ///
>@@ -255,8 +250,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
>@@ -398,8 +392,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
>@@ -409,7 +403,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,
>@@ -429,43 +423,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
>@@ -1558,39 +1552,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"));
>@@ -1622,9 +1620,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;
>@@ -1831,7 +1830,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)
>     {
>@@ -1848,31 +1847,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);
>
>@@ -1898,7 +1897,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))
> {}
>
>@@ -1943,9 +1942,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.
>@@ -1955,12 +1954,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.
> ///
>@@ -2028,14 +2027,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))
>@@ -2103,9 +2102,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.
>@@ -2113,8 +2112,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
>@@ -2122,9 +2121,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
>@@ -2133,8 +2132,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
>@@ -2166,9 +2165,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
>@@ -2183,8 +2182,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
>@@ -2252,9 +2251,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.
>@@ -2269,8 +2268,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.
>@@ -2285,11 +2284,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.
>@@ -2304,12 +2303,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.
>@@ -2344,9 +2343,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
>@@ -2360,8 +2359,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.
>@@ -2764,7 +2763,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))
>@@ -2779,7 +2778,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();
>@@ -3085,10 +3084,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 =
>@@ -3138,27 +3137,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"));
>@@ -3168,15 +3170,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"));
>@@ -3186,9 +3189,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"));
>@@ -3198,15 +3202,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"));
>@@ -3216,9 +3222,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"));
>@@ -3243,22 +3250,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())
>@@ -3269,23 +3276,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;
> }
>@@ -3305,7 +3312,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
>@@ -3339,7 +3346,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
>@@ -3347,18 +3354,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.
>@@ -3428,9 +3435,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.
>@@ -3441,22 +3448,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.
>@@ -3489,9 +3496,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.
>@@ -3503,8 +3510,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.
>@@ -3519,11 +3526,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.
>@@ -3538,12 +3545,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
>@@ -3571,9 +3578,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
>@@ -3584,8 +3591,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.
>@@ -3618,9 +3625,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.
>@@ -3632,8 +3639,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.
>@@ -3862,7 +3869,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))
>@@ -3877,7 +3884,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();
>@@ -3995,27 +4002,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"));
>@@ -4025,15 +4035,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"));
>@@ -4043,15 +4054,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"));
>@@ -4061,9 +4074,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"));
>@@ -4073,50 +4087,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;
> }
>@@ -4129,21 +4144,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
>@@ -4223,41 +4238,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]")
>-- 
>2.26.2.526.g744177e7f7-goog
>


More information about the Libabigail mailing list