diff --git a/include/abg-comparison.h b/include/abg-comparison.h index 4cf5b0c1..dca78726 100644 --- a/include/abg-comparison.h +++ b/include/abg-comparison.h @@ -600,6 +600,92 @@ public: set_parameter_type_name_regex_str(const string&); };// end class function_suppression::parameter_spec +class variable_suppression; + +/// A convenience typedef for a shared pointer to @ref +/// variable_suppression. +typedef shared_ptr variable_suppression_sptr; + +/// A convenience typedef for a vector of @ref +/// variable_suppression_sptr. +typedef vector variable_suppressions_type; + +/// The abstraction of a variable suppression specification. +/// +/// It specifies under which condition repots about a @ref var_diff +/// diff node should be dropped on the floor for the purpose of +/// reporting. +class variable_suppression : public suppression_base +{ + class priv; + typedef shared_ptr priv_sptr; + + priv_sptr priv_; + +public: + variable_suppression(const string& label, + const string& name, + const string& name_regex_str, + const string& symbol_name, + const string& symbol_name_regex_str, + const string& symbol_version, + const string& symbol_version_regex_str, + const string& type_name, + const string& type_name_regex_str); + + virtual ~variable_suppression(); + + const string& + get_name() const; + + void + set_name(const string&); + + const string& + get_name_regex_str() const; + + void + set_name_regex_str(const string&); + + const string& + get_symbol_name() const; + + void + set_symbol_name(const string&); + + const string& + get_symbol_name_regex_str() const; + + void + set_symbol_name_regex_str(const string&); + + const string& + get_symbol_version() const; + + void + set_symbol_version(const string&); + + const string& + get_symbol_version_regex_str() const; + + void + set_symbol_version_regex_str(const string&); + + const string& + get_type_name() const; + + void + set_type_name(const string&); + + const string& + get_type_name_regex_str() const; + + void + set_type_name_regex_str(const string&); + + bool + suppresses_diff(const diff* d) const; +}; // end class variable_suppression /// The context of the diff. This type holds various bits of /// information that is going to be used throughout the diffing of two diff --git a/src/abg-comparison.cc b/src/abg-comparison.cc index 52a85b39..d5951bbc 100644 --- a/src/abg-comparison.cc +++ b/src/abg-comparison.cc @@ -185,6 +185,21 @@ static const decl_diff_base* is_decl_diff(const diff* diff) {return dynamic_cast(diff);} +/// Test if a diff node is about differences between variables. +/// +/// @param diff the diff node to test. +/// +/// @return a pointer to the actual var_diff that @p diff is a type +/// of, iff it is about differences between variables. +static const var_diff* +is_var_diff(const diff* diff) +{ + const var_diff* d = dynamic_cast(diff); + if (d) + assert(is_decl_diff(diff)); + return d; +} + /// Test if a diff node is about differences between functions. /// /// @param diff the diff node to test. @@ -256,6 +271,9 @@ read_type_suppression(const ini::config::section& section); static function_suppression_sptr read_function_suppression(const ini::config::section& section); +static variable_suppression_sptr +read_variable_suppression(const ini::config::section& section); + /// Read a vector of suppression specifications from the sections of /// an ini::config. /// @@ -276,7 +294,8 @@ read_suppressions(const ini::config& config, i != config.get_sections().end(); ++i) if ((s = read_type_suppression(**i)) - || (s = read_function_suppression(**i))) + || (s = read_function_suppression(**i)) + || (s = read_variable_suppression(**i))) suppressions.push_back(s); } @@ -1571,6 +1590,598 @@ read_function_suppression(const ini::config::section& section) // +// + +/// The type of the private data of the @ref variable_suppression +/// type. +class variable_suppression::priv +{ + friend class variable_suppression; + + string name_; + string name_regex_str_; + mutable sptr_utils::regex_t_sptr name_regex_; + string symbol_name_; + string symbol_name_regex_str_; + mutable sptr_utils::regex_t_sptr symbol_name_regex_; + string symbol_version_; + string symbol_version_regex_str_; + mutable sptr_utils::regex_t_sptr symbol_version_regex_; + string type_name_; + string type_name_regex_str_; + mutable sptr_utils::regex_t_sptr type_name_regex_; + + priv(const string& name, + const string& name_regex_str, + const string& symbol_name, + const string& symbol_name_regex_str, + const string& symbol_version, + const string& symbol_version_regex_str, + const string& type_name, + const string& type_name_regex_str) + : name_(name), + name_regex_str_(name_regex_str), + symbol_name_(symbol_name), + symbol_name_regex_str_(symbol_name_regex_str), + symbol_version_(symbol_version), + symbol_version_regex_str_(symbol_version_regex_str), + type_name_(type_name), + type_name_regex_str_(type_name_regex_str) + {} + + /// 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_. + const sptr_utils::regex_t_sptr + get_name_regex() const + { + if (!name_regex_ && !name_regex_str_.empty()) + { + sptr_utils::regex_t_sptr r(new regex_t); + if (regcomp(r.get(), + name_regex_str_.c_str(), + REG_EXTENDED) == 0) + name_regex_ = r; + } + return name_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_. + const sptr_utils::regex_t_sptr + get_symbol_name_regex() const + { + if (!symbol_name_regex_ && !symbol_name_regex_str_.empty()) + { + sptr_utils::regex_t_sptr r(new regex_t); + if (regcomp(r.get(), + symbol_name_regex_str_.c_str(), + REG_EXTENDED) == 0) + symbol_name_regex_ = r; + } + return symbol_name_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_. + const sptr_utils::regex_t_sptr + get_symbol_version_regex() const + { + if (!symbol_version_regex_ && !symbol_version_regex_str_.empty()) + { + sptr_utils::regex_t_sptr r(new regex_t); + if (regcomp(r.get(), + symbol_version_regex_str_.c_str(), + REG_EXTENDED) == 0) + symbol_version_regex_ = r; + } + 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_. + const sptr_utils::regex_t_sptr + get_type_name_regex() const + { + if (!type_name_regex_ && !type_name_regex_str_.empty()) + { + sptr_utils::regex_t_sptr r(new regex_t); + if (regcomp(r.get(), + type_name_regex_str_.c_str(), + REG_EXTENDED) == 0) + type_name_regex_ = r; + } + return type_name_regex_; + } +};// end class variable_supppression::priv + +/// Constructor for the @ref variable_suppression type. +/// +/// @param label an informative text string that the evalution code +/// might use to designate this variable suppression specification in +/// error messages. This parameter might be empty, in which case it's +/// ignored at evaluation time. +/// +/// @param name the name of the variable the user wants the current +/// 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 +/// 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 +/// parameter might be empty, in which case it's ignored at evaluation +/// time. +/// +/// @param symbol_name the name of the symbol of the variable the user +/// wants the current specification to designate. This parameter +/// might be empty, in which case it's ignored at evaluation time. +/// +/// @param symbol_name_str if @p symbol_name is empty, this parameter +/// is a regular expression for a family of names of symbols of +/// variables the user wants the current specification to designate. +/// If @p symbol_name is not empty, then this parameter is ignored at +/// evaluation time. This parameter might be empty, in which case +/// it's ignored at evaluation time. +/// +/// @param symbol_version the version of the symbol of the variable +/// the user wants the current specification to designate. This +/// parameter might be empty, in which case it's ignored at evaluation +/// time. +/// +/// @param symbol_version_regex if @p symbol_version is empty, then +/// this parameter is a regular expression for a family of versions of +/// symbol for the variables the user wants the current specification +/// to designate. If @p symbol_version is not empty, then this +/// parameter is ignored at evaluation time. This parameter might be +/// empty, in which case it's ignored at evaluation time. +/// +/// @param type_name the name of the type of the variable the user +/// 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 +/// 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 +/// evluation time. This parameter might be empty, in which case it's +/// ignored at evaluation time. +variable_suppression::variable_suppression(const string& label, + const string& name, + const string& name_regex_str, + const string& symbol_name, + const string& symbol_name_regex_str, + const string& symbol_version, + const string& symbol_version_regex, + const string& type_name, + const string& type_name_regex_str) + : suppression_base(label), + priv_(new priv(name, name_regex_str, + symbol_name, symbol_name_regex_str, + symbol_version, symbol_version_regex, + type_name, type_name_regex_str)) +{} + +/// Virtual destructor for the @erf variable_suppression type. +/// variable_suppression type. +variable_suppression::~variable_suppression() +{} + +/// Getter for the name of the variable the user wants the current +/// specification to designate. This property might be empty, in +/// which case it's ignored at evaluation time. +/// +/// @return the name of the variable. +const string& +variable_suppression::get_name() const +{return priv_->name_;} + +/// Setter for the name of the variable the user wants the current +/// specification to designate. This property might be empty, in +/// which case it's ignored at evaluation time. +/// +/// @param n the new name of the variable to set. +void +variable_suppression::set_name(const string& n) +{priv_->name_ = n;} + +/// Getter for the regular expression for a family of names of +/// variables the user wants the current specification to designate. +/// If the variable name as returned by +/// variable_suppression::get_name() is not empty, then this property +/// is ignored at evaluation time. This property might be empty, in +/// 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_;} + +/// Setter for the regular expression for a family of names of +/// variables the user wants the current specification to designate. +/// If the variable name as returned by +/// variable_suppression::get_name() is not empty, then this property +/// is ignored at evaluation time. This property might be empty, in +/// which case it's ignored at evaluation time. +/// +/// @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;} + +/// Getter for the name of the symbol of the variable the user wants +/// the current specification to designate. +/// +/// This property might be empty, in which case it is ignored at +/// evaluation time. +/// +/// @return the name of the symbol of the variable. +const string& +variable_suppression::get_symbol_name() const +{return priv_->symbol_name_;} + +/// Setter for the name of the symbol of the variable the user wants +/// the current specification to designate. +/// +/// This property might be empty, in which case it is ignored at +/// evaluation time. +/// +/// @param n the new name of the symbol of the variable. +void +variable_suppression::set_symbol_name(const string& n) +{priv_->symbol_name_ = n;} + +/// Getter of the regular expression for a family of symbol names of +/// the variables this specification is about to designate. +/// +/// This property might be empty, in which case it's ignored at +/// evaluation time. Otherwise, it is taken in account iff the +/// property returned by variable_suppression::get_symbol_name() is +/// 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_;} + +/// Setter of the regular expression for a family of symbol names of +/// the variables this specification is about to designate. +/// +/// This property might be empty, in which case it's ignored at +/// evaluation time. Otherwise, it is taken in account iff the +/// property returned by variable_suppression::get_symbol_name() is +/// empty. +/// +/// @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;} + +/// Getter for the version of the symbol of the variable the user +/// wants the current specification to designate. This property might +/// be empty, in which case it's ignored at evaluation time. +/// +/// @return the symbol version of the variable. +const string& +variable_suppression::get_symbol_version() const +{return priv_->symbol_version_;} + +/// Setter for the version of the symbol of the variable the user +/// wants the current specification to designate. This property might +/// be empty, in which case it's ignored at evaluation time. +/// +/// @return the new symbol version of the variable. +void +variable_suppression::set_symbol_version(const string& v) +{priv_->symbol_version_ = v;} + +/// Getter of the regular expression for a family of versions of +/// symbol for the variables the user wants the current specification +/// to designate. If @p symbol_version is not empty, then this +/// property is ignored at evaluation time. This property might be +/// empty, in which case it's ignored at evaluation time. +/// +/// @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_;} + +/// Setter of the regular expression for a family of versions of +/// symbol for the variables the user wants the current specification +/// to designate. If @p symbol_version is not empty, then this +/// property is ignored at evaluation time. This property might be +/// empty, in which case it's ignored at evaluation time. +/// +/// @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;} + +/// Getter for the name of the type of the variable the user wants the +/// current specification to designate. +/// +/// This property might be empty, in which case it's ignored at +/// evaluation time. +/// +/// @return the name of the variable type. +const string& +variable_suppression::get_type_name() const +{return priv_->type_name_;} + +/// Setter for the name of the type of the variable the user wants the +/// current specification to designate. +/// +/// This property might be empty, in which case it's ignored at +/// evaluation time. +/// +/// @param n the new name of the variable type. +void +variable_suppression::set_type_name(const string& n) +{priv_->type_name_ = n;} + +/// Getter for the regular expression for a family of type names of +/// variables the user wants the current specification to designate. +/// +/// If the type name as returned by +/// variable_suppression::get_type_name() is not empty, then this +/// property is ignored at evaluation time. This property might be +/// 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_;} + +/// Setter for the regular expression for a family of type names of +/// variables the user wants the current specification to designate. +/// +/// If the type name as returned by +/// variable_suppression::get_type_name() is not empty, then this +/// property is ignored at evaluation time. This property might be +/// empty, in which case it's ignored at evaluation time. +/// +/// @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;} + +/// Evaluate this suppression specification on a given diff node and +/// say if the diff node should be suppressed or not. +/// +/// @param diff the diff node to evaluate this suppression +/// specification against. +/// +/// @return true if @p diff should be suppressed. +bool +variable_suppression::suppresses_diff(const diff* diff) const +{ + const var_diff* d = is_var_diff(diff); + if (!d) + return false; + + var_decl_sptr fv = is_var_decl(d->first_subject()), + sv = is_var_decl(d->second_subject()); + + assert(fv && sv); + + string fv_name = fv->get_name(), sv_name = sv->get_name(); + + // Check for "name" property match. + if (!get_name().empty()) + { + if (get_name() != fv_name && get_name () != sv_name) + return false; + } + else + { + // If the "name" property is empty, then consider checking for the + // "name_regex" property match + if (get_name().empty()) + { + const sptr_utils::regex_t_sptr name_regex = priv_->get_name_regex(); + if (name_regex + && (regexec(name_regex.get(), fv_name.c_str(), + 0, NULL, 0) != 0 + && regexec(name_regex.get(), sv_name.c_str(), + 0, NULL, 0) != 0)) + return false; + } + } + + // Check for the symbol_name property match. + string fv_sym_name = fv->get_symbol() ? fv->get_symbol()->get_name() : ""; + string sv_sym_name = sv->get_symbol() ? sv->get_symbol()->get_name() : ""; + if (!get_symbol_name().empty()) + { + if (get_symbol_name() != fv_sym_name && get_symbol_name() != sv_sym_name) + return false; + } + else + { + const sptr_utils::regex_t_sptr sym_name_regex = + priv_->get_symbol_name_regex(); + if (sym_name_regex + && (regexec(sym_name_regex.get(), fv_sym_name.c_str(), + 0, NULL, 0) != 0 + && regexec(sym_name_regex.get(), sv_sym_name.c_str(), + 0, NULL, 0) != 0)) + return false; + } + + // Check for symbol_version and symbol_version_regexp property match + string fv_sym_version = + fv->get_symbol() ? fv->get_symbol()->get_version().str() : ""; + string sv_sym_version = + sv->get_symbol() ? fv->get_symbol()->get_version().str() : ""; + if (!get_symbol_version().empty()) + { + if (get_symbol_version() != fv_sym_version + && get_symbol_version() != sv_sym_version) + return false; + } + else + { + const sptr_utils::regex_t_sptr symbol_version_regex = + priv_->get_symbol_version_regex(); + if (symbol_version_regex + && (regexec(symbol_version_regex.get(), + fv_sym_version.c_str(), + 0, NULL, 0) != 0 + && regexec(symbol_version_regex.get(), + sv_sym_version.c_str(), + 0, NULL, 0) != 0)) + return false; + } + + string fv_type_name = + get_type_declaration(fv->get_type())->get_qualified_name(); + string sv_type_name = + get_type_declaration(sv->get_type())->get_qualified_name(); + + // Check for the "type_name" and tye_name_regex properties match. + if (!get_type_name().empty()) + { + if (get_type_name() != fv_type_name && get_type_name() != sv_type_name) + return false; + } + else + { + if (get_type_name().empty()) + { + const sptr_utils::regex_t_sptr type_name_regex = + priv_->get_type_name_regex(); + if (type_name_regex + && (regexec(type_name_regex.get(), fv_type_name.c_str(), + 0, NULL, 0) != 0 + && regexec(type_name_regex.get(), sv_type_name.c_str(), + 0, NULL, 0) != 0)) + return false; + } + } + + return true; +} + +/// Parse variable suppression specification, build a resulting @ref +/// variable_suppression type and return a shared pointer to that +/// object. +/// +/// @return a shared pointer to the newly built @ref +/// variable_suppression. If the variable suppression specification +/// could not be parsed then a nil shared pointer is returned. +static variable_suppression_sptr +read_variable_suppression(const ini::config::section& section) +{ + variable_suppression_sptr result; + + if (section.get_name() != "suppress_variable") + return result; + + ini::config::property_sptr label_prop = section.find_property("label"); + string label_str = (label_prop && !label_prop->second.empty() + ? label_prop->second + : ""); + + ini::config::property_sptr name_prop = section.find_property("name"); + string name_str = (name_prop && !name_prop->second.empty() + ? name_prop->second + : ""); + + ini::config::property_sptr name_regex_prop = + section.find_property("name_regexp"); + string name_regex_str = (name_regex_prop && !name_regex_prop->second.empty() + ? name_regex_prop->second + : ""); + + ini::config::property_sptr sym_name_prop = + section.find_property("symbol_name"); + string symbol_name = (sym_name_prop && !sym_name_prop->second.empty() + ? sym_name_prop->second + : ""); + + ini::config::property_sptr sym_name_regex_prop = + section.find_property("symbol_name_regexp"); + string symbol_name_regex_str = + (sym_name_regex_prop && !sym_name_regex_prop->second.empty() + ? sym_name_regex_prop->second + : ""); + + ini::config::property_sptr sym_version_prop = + section.find_property("symbol_version"); + string symbol_version = + (sym_version_prop && !sym_version_prop->second.empty() + ? sym_version_prop->second + : ""); + + ini::config::property_sptr sym_version_regex_prop = + section.find_property("symbol_version_regexp"); + string symbol_version_regex_str = + (sym_version_regex_prop && !sym_version_regex_prop->second.empty() + ? sym_version_regex_prop->second + : ""); + + ini::config::property_sptr type_name_prop = + section.find_property("type_name"); + string type_name_str = (type_name_prop && !type_name_prop->second.empty() + ? type_name_prop->second + : ""); + + ini::config::property_sptr type_name_regex_prop = + section.find_property("type_name_regexp"); + string type_name_regex_str = + (type_name_regex_prop && !type_name_regex_prop->second.empty() + ? type_name_regex_prop->second + : ""); + + if (label_str.empty() + && name_str.empty() + && name_regex_str.empty() + && symbol_name.empty() + && symbol_name_regex_str.empty() + && symbol_version.empty() + && symbol_version_regex_str.empty() + && type_name_str.empty() + && type_name_regex_str.empty()) + return result; + + result.reset(new variable_suppression(label_str, name_str, name_regex_str, + symbol_name, symbol_name_regex_str, + symbol_version, symbol_version_regex_str, + type_name_str, type_name_regex_str)); + return result; +} + +// + /// The private member (pimpl) for @ref diff_context. struct diff_context::priv { diff --git a/tests/Makefile.am b/tests/Makefile.am index 30a4db65..8b23825f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -450,6 +450,28 @@ tests/data/test-diff-suppr/test6-fn-suppr-report-4.txt \ tests/data/test-diff-suppr/test6-fn-suppr-v0.cc \ tests/data/test-diff-suppr/test6-fn-suppr-v1.cc \ tests/data/test-diff-suppr/test6-fn-suppr-version-script \ +tests/data/test-diff-suppr/libtest7-var-suppr-v0.so \ +tests/data/test-diff-suppr/libtest7-var-suppr-v1.so \ +tests/data/test-diff-suppr/test7-var-suppr-v0.cc \ +tests/data/test-diff-suppr/test7-var-suppr-v1.cc \ +tests/data/test-diff-suppr/test7-var-suppr-1.suppr \ +tests/data/test-diff-suppr/test7-var-suppr-2.suppr \ +tests/data/test-diff-suppr/test7-var-suppr-3.suppr \ +tests/data/test-diff-suppr/test7-var-suppr-4.suppr \ +tests/data/test-diff-suppr/test7-var-suppr-5.suppr \ +tests/data/test-diff-suppr/test7-var-suppr-6.suppr \ +tests/data/test-diff-suppr/test7-var-suppr-7.suppr \ +tests/data/test-diff-suppr/test7-var-suppr-8.suppr \ +tests/data/test-diff-suppr/test7-var-suppr-report-0.txt \ +tests/data/test-diff-suppr/test7-var-suppr-report-1.txt \ +tests/data/test-diff-suppr/test7-var-suppr-report-2.txt \ +tests/data/test-diff-suppr/test7-var-suppr-report-3.txt \ +tests/data/test-diff-suppr/test7-var-suppr-report-4.txt \ +tests/data/test-diff-suppr/test7-var-suppr-report-5.txt \ +tests/data/test-diff-suppr/test7-var-suppr-report-6.txt \ +tests/data/test-diff-suppr/test7-var-suppr-report-7.txt \ +tests/data/test-diff-suppr/test7-var-suppr-report-8.txt \ +tests/data/test-diff-suppr/test7-var-suppr-version-script \ \ data/test-lookup-syms/test0.cc \ data/test-lookup-syms/test0.o \ diff --git a/tests/data/test-diff-suppr/libtest7-var-suppr-v0.so b/tests/data/test-diff-suppr/libtest7-var-suppr-v0.so new file mode 100755 index 00000000..e21844ba Binary files /dev/null and b/tests/data/test-diff-suppr/libtest7-var-suppr-v0.so differ diff --git a/tests/data/test-diff-suppr/libtest7-var-suppr-v1.so b/tests/data/test-diff-suppr/libtest7-var-suppr-v1.so new file mode 100755 index 00000000..b7537fd1 Binary files /dev/null and b/tests/data/test-diff-suppr/libtest7-var-suppr-v1.so differ diff --git a/tests/data/test-diff-suppr/test7-var-suppr-1.suppr b/tests/data/test-diff-suppr/test7-var-suppr-1.suppr new file mode 100644 index 00000000..489fdd10 --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-1.suppr @@ -0,0 +1,2 @@ +[suppress_variable] + name = var0 diff --git a/tests/data/test-diff-suppr/test7-var-suppr-2.suppr b/tests/data/test-diff-suppr/test7-var-suppr-2.suppr new file mode 100644 index 00000000..ac05ec18 --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-2.suppr @@ -0,0 +1,2 @@ +[suppress_variable] + name = var1 diff --git a/tests/data/test-diff-suppr/test7-var-suppr-3.suppr b/tests/data/test-diff-suppr/test7-var-suppr-3.suppr new file mode 100644 index 00000000..ff4d1f75 --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-3.suppr @@ -0,0 +1,2 @@ +[suppress_variable] + symbol_name_regexp = ^v.*0$ diff --git a/tests/data/test-diff-suppr/test7-var-suppr-4.suppr b/tests/data/test-diff-suppr/test7-var-suppr-4.suppr new file mode 100644 index 00000000..823b2680 --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-4.suppr @@ -0,0 +1,2 @@ +[suppress_variable] + symbol_name_regexp = ^v.*1$ diff --git a/tests/data/test-diff-suppr/test7-var-suppr-5.suppr b/tests/data/test-diff-suppr/test7-var-suppr-5.suppr new file mode 100644 index 00000000..0a171b09 --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-5.suppr @@ -0,0 +1,2 @@ +[suppress_variable] + symbol_version = VERSION_1.0 diff --git a/tests/data/test-diff-suppr/test7-var-suppr-6.suppr b/tests/data/test-diff-suppr/test7-var-suppr-6.suppr new file mode 100644 index 00000000..3e4e6d05 --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-6.suppr @@ -0,0 +1,2 @@ +[suppress_variable] + symbol_version_regexp = ^VERSION_1.*$ diff --git a/tests/data/test-diff-suppr/test7-var-suppr-7.suppr b/tests/data/test-diff-suppr/test7-var-suppr-7.suppr new file mode 100644 index 00000000..70bf1d37 --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-7.suppr @@ -0,0 +1,3 @@ +[suppress_variable] + name = var1 + type_name = S1* \ No newline at end of file diff --git a/tests/data/test-diff-suppr/test7-var-suppr-8.suppr b/tests/data/test-diff-suppr/test7-var-suppr-8.suppr new file mode 100644 index 00000000..ccc1c2dc --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-8.suppr @@ -0,0 +1,3 @@ +[suppress_variable] + name = var0 + type_name = ^S0 diff --git a/tests/data/test-diff-suppr/test7-var-suppr-report-0.txt b/tests/data/test-diff-suppr/test7-var-suppr-report-0.txt new file mode 100644 index 00000000..506d6663 --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-report-0.txt @@ -0,0 +1,24 @@ +Functions changes summary: 0 Removed, 0 Changed, 0 Added function +Variables changes summary: 0 Removed, 2 Changed, 0 Added variables + +2 Changed variables: + + 'S1* var1' was changed: + type of variable changed: + in pointed to type 'struct S1': + size changed from 32 to 64 bits + 1 data member insertion: + 'char S1::inserted_member', at offset 0 (in bits) + 1 data member change: + 'int S1::m0' offset changed from 0 to 32 + + 'S0* var0' was changed: + type of variable changed: + in pointed to type 'struct S0': + size changed from 32 to 64 bits + 1 data member insertion: + 'char S0::inserted_member', at offset 0 (in bits) + 1 data member change: + 'int S0::m0' offset changed from 0 to 32 + + diff --git a/tests/data/test-diff-suppr/test7-var-suppr-report-1.txt b/tests/data/test-diff-suppr/test7-var-suppr-report-1.txt new file mode 100644 index 00000000..5230a483 --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-report-1.txt @@ -0,0 +1,14 @@ +Functions changes summary: 0 Removed, 0 Changed, 0 Added function +Variables changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added variable + +1 Changed variable: + 'S1* var1' was changed: + type of variable changed: + in pointed to type 'struct S1': + size changed from 32 to 64 bits + 1 data member insertion: + 'char S1::inserted_member', at offset 0 (in bits) + 1 data member change: + 'int S1::m0' offset changed from 0 to 32 + + diff --git a/tests/data/test-diff-suppr/test7-var-suppr-report-2.txt b/tests/data/test-diff-suppr/test7-var-suppr-report-2.txt new file mode 100644 index 00000000..02ca797a --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-report-2.txt @@ -0,0 +1,14 @@ +Functions changes summary: 0 Removed, 0 Changed, 0 Added function +Variables changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added variable + +1 Changed variable: + 'S0* var0' was changed: + type of variable changed: + in pointed to type 'struct S0': + size changed from 32 to 64 bits + 1 data member insertion: + 'char S0::inserted_member', at offset 0 (in bits) + 1 data member change: + 'int S0::m0' offset changed from 0 to 32 + + diff --git a/tests/data/test-diff-suppr/test7-var-suppr-report-3.txt b/tests/data/test-diff-suppr/test7-var-suppr-report-3.txt new file mode 100644 index 00000000..5230a483 --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-report-3.txt @@ -0,0 +1,14 @@ +Functions changes summary: 0 Removed, 0 Changed, 0 Added function +Variables changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added variable + +1 Changed variable: + 'S1* var1' was changed: + type of variable changed: + in pointed to type 'struct S1': + size changed from 32 to 64 bits + 1 data member insertion: + 'char S1::inserted_member', at offset 0 (in bits) + 1 data member change: + 'int S1::m0' offset changed from 0 to 32 + + diff --git a/tests/data/test-diff-suppr/test7-var-suppr-report-4.txt b/tests/data/test-diff-suppr/test7-var-suppr-report-4.txt new file mode 100644 index 00000000..02ca797a --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-report-4.txt @@ -0,0 +1,14 @@ +Functions changes summary: 0 Removed, 0 Changed, 0 Added function +Variables changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added variable + +1 Changed variable: + 'S0* var0' was changed: + type of variable changed: + in pointed to type 'struct S0': + size changed from 32 to 64 bits + 1 data member insertion: + 'char S0::inserted_member', at offset 0 (in bits) + 1 data member change: + 'int S0::m0' offset changed from 0 to 32 + + diff --git a/tests/data/test-diff-suppr/test7-var-suppr-report-5.txt b/tests/data/test-diff-suppr/test7-var-suppr-report-5.txt new file mode 100644 index 00000000..d4be89bc --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-report-5.txt @@ -0,0 +1,3 @@ +Functions changes summary: 0 Removed, 0 Changed, 0 Added function +Variables changes summary: 0 Removed, 0 Changed (2 filtered out), 0 Added variable + diff --git a/tests/data/test-diff-suppr/test7-var-suppr-report-6.txt b/tests/data/test-diff-suppr/test7-var-suppr-report-6.txt new file mode 100644 index 00000000..d4be89bc --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-report-6.txt @@ -0,0 +1,3 @@ +Functions changes summary: 0 Removed, 0 Changed, 0 Added function +Variables changes summary: 0 Removed, 0 Changed (2 filtered out), 0 Added variable + diff --git a/tests/data/test-diff-suppr/test7-var-suppr-report-7.txt b/tests/data/test-diff-suppr/test7-var-suppr-report-7.txt new file mode 100644 index 00000000..02ca797a --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-report-7.txt @@ -0,0 +1,14 @@ +Functions changes summary: 0 Removed, 0 Changed, 0 Added function +Variables changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added variable + +1 Changed variable: + 'S0* var0' was changed: + type of variable changed: + in pointed to type 'struct S0': + size changed from 32 to 64 bits + 1 data member insertion: + 'char S0::inserted_member', at offset 0 (in bits) + 1 data member change: + 'int S0::m0' offset changed from 0 to 32 + + diff --git a/tests/data/test-diff-suppr/test7-var-suppr-report-8.txt b/tests/data/test-diff-suppr/test7-var-suppr-report-8.txt new file mode 100644 index 00000000..506d6663 --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-report-8.txt @@ -0,0 +1,24 @@ +Functions changes summary: 0 Removed, 0 Changed, 0 Added function +Variables changes summary: 0 Removed, 2 Changed, 0 Added variables + +2 Changed variables: + + 'S1* var1' was changed: + type of variable changed: + in pointed to type 'struct S1': + size changed from 32 to 64 bits + 1 data member insertion: + 'char S1::inserted_member', at offset 0 (in bits) + 1 data member change: + 'int S1::m0' offset changed from 0 to 32 + + 'S0* var0' was changed: + type of variable changed: + in pointed to type 'struct S0': + size changed from 32 to 64 bits + 1 data member insertion: + 'char S0::inserted_member', at offset 0 (in bits) + 1 data member change: + 'int S0::m0' offset changed from 0 to 32 + + diff --git a/tests/data/test-diff-suppr/test7-var-suppr-v0.cc b/tests/data/test-diff-suppr/test7-var-suppr-v0.cc new file mode 100644 index 00000000..8447200b --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-v0.cc @@ -0,0 +1,19 @@ +// Compile this with: +// g++ -Wall -g -shared -Wl,--version-script=test7-var-suppr-version-script -o libtest7-var-suppr-v0.so test7-var-suppr-v0.cc +struct S0 +{ + int m0; +}; + +struct S1 +{ + int m0; +}; + +S0* var0; + +asm(".symver var0,var0@VERSION_1.0"); + +S1* var1; + +asm(".symver var1,var1@VERSION_1.0"); diff --git a/tests/data/test-diff-suppr/test7-var-suppr-v1.cc b/tests/data/test-diff-suppr/test7-var-suppr-v1.cc new file mode 100644 index 00000000..9ef2a816 --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-v1.cc @@ -0,0 +1,22 @@ +// Compile this with: +// g++ -Wall -g -shared -Wl,--version-script=test7-var-suppr-version-script -o libtest7-var-suppr-v1.so test7-var-suppr-v1.cc + +struct S0 +{ + char inserted_member; + int m0; +}; + +struct S1 +{ + char inserted_member; + int m0; +}; + +S0* var0; + +asm(".symver var0,var0@VERSION_1.0"); + +S1* var1; + +asm(".symver var1,var1@VERSION_1.0"); diff --git a/tests/data/test-diff-suppr/test7-var-suppr-version-script b/tests/data/test-diff-suppr/test7-var-suppr-version-script new file mode 100644 index 00000000..cfe77d75 --- /dev/null +++ b/tests/data/test-diff-suppr/test7-var-suppr-version-script @@ -0,0 +1,3 @@ +VERSION_1.0 { + global : var0; var1; +}; \ No newline at end of file diff --git a/tests/test-diff-suppr.cc b/tests/test-diff-suppr.cc index 43ccc465..38fed707 100644 --- a/tests/test-diff-suppr.cc +++ b/tests/test-diff-suppr.cc @@ -247,6 +247,78 @@ InOutSpec in_out_specs[] = "data/test-diff-suppr/test6-fn-suppr-report-3.txt", "output/test-diff-suppr/test6-fn-suppr-report-3.txt", }, + { + "data/test-diff-suppr/libtest7-var-suppr-v0.so", + "data/test-diff-suppr/libtest7-var-suppr-v1.so", + "", + "", + "data/test-diff-suppr/test7-var-suppr-report-0.txt", + "output/test-diff-suppr/test7-var-suppr-report-0.txt" + }, + { + "data/test-diff-suppr/libtest7-var-suppr-v0.so", + "data/test-diff-suppr/libtest7-var-suppr-v1.so", + "data/test-diff-suppr/test7-var-suppr-1.suppr", + "", + "data/test-diff-suppr/test7-var-suppr-report-1.txt", + "output/test-diff-suppr/test7-var-suppr-report-1.txt" + }, + { + "data/test-diff-suppr/libtest7-var-suppr-v0.so", + "data/test-diff-suppr/libtest7-var-suppr-v1.so", + "data/test-diff-suppr/test7-var-suppr-2.suppr", + "", + "data/test-diff-suppr/test7-var-suppr-report-2.txt", + "output/test-diff-suppr/test7-var-suppr-report-2.txt" + }, + { + "data/test-diff-suppr/libtest7-var-suppr-v0.so", + "data/test-diff-suppr/libtest7-var-suppr-v1.so", + "data/test-diff-suppr/test7-var-suppr-3.suppr", + "", + "data/test-diff-suppr/test7-var-suppr-report-3.txt", + "output/test-diff-suppr/test7-var-suppr-report-3.txt" + }, + { + "data/test-diff-suppr/libtest7-var-suppr-v0.so", + "data/test-diff-suppr/libtest7-var-suppr-v1.so", + "data/test-diff-suppr/test7-var-suppr-4.suppr", + "", + "data/test-diff-suppr/test7-var-suppr-report-4.txt", + "output/test-diff-suppr/test7-var-suppr-report-4.txt" + }, + { + "data/test-diff-suppr/libtest7-var-suppr-v0.so", + "data/test-diff-suppr/libtest7-var-suppr-v1.so", + "data/test-diff-suppr/test7-var-suppr-5.suppr", + "", + "data/test-diff-suppr/test7-var-suppr-report-5.txt", + "output/test-diff-suppr/test7-var-suppr-report-5.txt" + }, + { + "data/test-diff-suppr/libtest7-var-suppr-v0.so", + "data/test-diff-suppr/libtest7-var-suppr-v1.so", + "data/test-diff-suppr/test7-var-suppr-6.suppr", + "", + "data/test-diff-suppr/test7-var-suppr-report-6.txt", + "output/test-diff-suppr/test7-var-suppr-report-6.txt" + }, + { + "data/test-diff-suppr/libtest7-var-suppr-v0.so", + "data/test-diff-suppr/libtest7-var-suppr-v1.so", + "data/test-diff-suppr/test7-var-suppr-7.suppr", + "", + "data/test-diff-suppr/test7-var-suppr-report-7.txt", + "output/test-diff-suppr/test7-var-suppr-report-7.txt" + }, + { + "data/test-diff-suppr/libtest7-var-suppr-v0.so", + "data/test-diff-suppr/libtest7-var-suppr-v1.so", + "data/test-diff-suppr/test7-var-suppr-8.suppr", + "", + "data/test-diff-suppr/test7-var-suppr-report-8.txt", + "output/test-diff-suppr/test7-var-suppr-report-8.txt" + }, // This should be the last entry {NULL, NULL, NULL, NULL, NULL, NULL} };