subrange_type();
public:
+ /// This class is to hold the value of the bound of a subrange.
+ /// The value can be either signed or unsigned, at least when it
+ /// comes from DWARF. The class keeps the sign information, but
+ /// allows users to access the value as signed or unsigned as they
+ /// see fit.
+ class bound_value
+ {
+ public:
+ enum signedness
+ {
+ UNSIGNED_SIGNEDNESS,
+ SIGNED_SIGNEDNESS
+ };
+
+ private:
+ signedness s_;
+
+ public:
+ union
+ {
+ uint64_t unsigned_;
+ int64_t signed_;
+ } v_;
+ bound_value();
+ bound_value(uint64_t);
+ bound_value(int64_t);
+ enum signedness get_signedness() const;
+ void set_signedness(enum signedness s);
+ int64_t get_signed_value() const;
+ uint64_t get_unsigned_value();
+ void set_unsigned(uint64_t v);
+ void set_signed(int64_t v);
+ }; //end class bound_value
+
/// Hasher for an instance of array::subrange
struct hash;
subrange_type(const environment* env,
const string& name,
- size_t lower_bound,
- size_t upper_bound,
+ bound_value lower_bound,
+ bound_value upper_bound,
type_base_sptr& underlying_type,
const location& loc,
translation_unit::language l = translation_unit::LANG_C11);
subrange_type(const environment* env,
const string& name,
- size_t lower_bound,
- size_t upper_bound,
+ bound_value lower_bound,
+ bound_value upper_bound,
const location& loc,
translation_unit::language l = translation_unit::LANG_C11);
subrange_type(const environment* env,
const string& name,
- size_t upper_bound,
+ bound_value upper_bound,
const location& loc,
translation_unit::language l = translation_unit::LANG_C11);
void
set_underlying_type(const type_base_sptr &);
- size_t
+ int64_t
get_upper_bound() const;
- size_t
+ int64_t
get_lower_bound() const;
void
- set_upper_bound(size_t ub);
+ set_upper_bound(int64_t ub);
void
- set_lower_bound(size_t lb);
+ set_lower_bound(int64_t lb);
- size_t
+ uint64_t
get_length() const;
bool
uint64_t& cst);
static bool
+die_signed_constant_attribute(Dwarf_Die*die,
+ unsigned attr_name,
+ int64_t& cst);
+
+static bool
+die_constant_attribute(Dwarf_Die *die,
+ unsigned attr_name,
+ array_type_def::subrange_type::bound_value &value);
+
+static bool
+die_attribute_has_form(Dwarf_Die* die,
+ unsigned attr_name,
+ unsigned int form);
+
+static bool
+die_attribute_is_signed(Dwarf_Die* die, unsigned attr_name);
+
+static bool
+die_attribute_is_unsigned(Dwarf_Die* die, unsigned attr_name);
+
+static bool
+die_attribute_has_no_signedness(Dwarf_Die* die, unsigned attr_name);
+
+static bool
die_address_attribute(Dwarf_Die* die, unsigned attr_name, Dwarf_Addr& result);
static string
static void
maybe_canonicalize_type(Dwarf_Die* die, read_context& ctxt);
-static int
+static uint64_t
get_default_array_lower_bound(translation_unit::language l);
static bool
return true;
}
+/// Read a signed constant value from a given attribute.
+///
+/// The signed constant expected must be of form DW_FORM_sdata.
+///
+/// @param die the DIE to get the attribute from.
+///
+/// @param attr_name the attribute name.
+///
+/// @param cst the resulting signed constant read.
+///
+/// @return true iff a signed constant attribute of the name @p
+/// attr_name was found on the DIE @p die.
+static bool
+die_signed_constant_attribute(Dwarf_Die *die,
+ unsigned attr_name,
+ int64_t& cst)
+{
+ if (!die)
+ return false;
+
+ Dwarf_Attribute attr;
+ Dwarf_Sword result = 0;
+ if (!dwarf_attr_integrate(die, attr_name, &attr)
+ || dwarf_formsdata(&attr, &result))
+ return false;
+
+ cst = result;
+ return true;
+}
+
+/// Read the value of a constant attribute that is either signed or
+/// unsigned into a array_type_def::subrange_type::bound_value value.
+///
+/// The bound_value instance will capture the actual signedness of the
+/// read attribute.
+///
+/// @param die the DIE from which to read the value of the attribute.
+///
+/// @param attr_name the attribute name to consider.
+///
+/// @param value the resulting value read from attribute @p attr_name
+/// on DIE @p die.
+///
+/// @return true iff DIE @p die has an attribute named @p attr_name
+/// with a constant value.
+static bool
+die_constant_attribute(Dwarf_Die *die,
+ unsigned attr_name,
+ array_type_def::subrange_type::bound_value &value)
+{
+ if (die_attribute_is_unsigned(die, attr_name)
+ || die_attribute_has_no_signedness(die, attr_name))
+ {
+ uint64_t l = 0;
+ if (!die_unsigned_constant_attribute(die, attr_name, l))
+ return false;
+ value.set_unsigned(l);
+ }
+ else
+ {
+ int64_t l = 0;
+ if (!die_signed_constant_attribute(die, attr_name, l))
+ return false;
+ value.set_signed(l);
+ }
+ return true;
+}
+
+/// Test if a given attribute on a DIE has a particular form.
+///
+/// @param die the DIE to consider.
+///
+/// @param attr_name the attribute name to consider on DIE @p die.
+///
+/// @param attr_form the attribute form that we expect attribute @p
+/// attr_name has on DIE @p die.
+///
+/// @return true iff the attribute named @p attr_name on DIE @p die
+/// has the form @p attr_form.
+static bool
+die_attribute_has_form(Dwarf_Die *die,
+ unsigned attr_name,
+ unsigned int attr_form)
+{
+ Dwarf_Attribute attr;
+ if (!dwarf_attr_integrate(die, attr_name, &attr))
+ return false;
+
+ return dwarf_hasform(&attr, attr_form);
+}
+
+/// Test if a given DIE attribute is signed.
+///
+/// @param die the DIE to consider.
+///
+/// @param attr_name the attribute name to consider.
+///
+/// @return true iff the attribute named @p attr_name on DIE @p die is
+/// signed.
+static bool
+die_attribute_is_signed(Dwarf_Die* die, unsigned attr_name)
+{
+ if (die_attribute_has_form(die, attr_name, DW_FORM_sdata))
+ return true;
+ return false;
+}
+
+/// Test if a given DIE attribute is unsigned.
+///
+/// @param die the DIE to consider.
+///
+/// @param attr_name the attribute name to consider.
+///
+/// @return true iff the attribute named @p attr_name on DIE @p die is
+/// unsigned.
+static bool
+die_attribute_is_unsigned(Dwarf_Die* die, unsigned attr_name)
+{
+ if (die_attribute_has_form(die, attr_name, DW_FORM_udata))
+ return true;
+ return false;
+}
+
+/// Test if a given DIE attribute is neither explicitely signed nor
+/// unsigned. Usually this is the case for attribute of the form
+/// DW_FORM_data*.
+///
+/// @param die the DIE to consider.
+///
+/// @param attr_name the name of the attribute to consider.
+///
+/// @return true iff the attribute named @p attr_name of DIE @p die is
+/// neither specifically signed nor unsigned.
+static bool
+die_attribute_has_no_signedness(Dwarf_Die *die, unsigned attr_name)
+{
+ return (!die_attribute_is_unsigned(die, attr_name)
+ && !die_attribute_is_signed(die, attr_name));
+}
+
/// Get the value of a DIE attribute; that value is meant to be a
/// flag.
///
/// @param l the language of the translation unit.
///
/// @return the default array lower bound value.
-static int
+static uint64_t
get_default_array_lower_bound(translation_unit::language l)
{
int value = 0;
string name = die_name(die);
translation_unit::language language = ctxt.cur_transl_unit()->get_language();
- uint64_t lower_bound = get_default_array_lower_bound(language);
- uint64_t upper_bound = 0;
+ array_type_def::subrange_type::bound_value lower_bound =
+ get_default_array_lower_bound(language);
+ array_type_def::subrange_type::bound_value upper_bound;
uint64_t count = 0;
bool is_infinite = false;
// values of the subrange.
//
// So let's look for DW_AT_lower_bound first.
- die_unsigned_constant_attribute(die, DW_AT_lower_bound, lower_bound);
+ die_constant_attribute(die, DW_AT_lower_bound, lower_bound);
// Then, DW_AT_upper_bound.
- if (!die_unsigned_constant_attribute(die, DW_AT_upper_bound, upper_bound))
+ if (!die_constant_attribute(die, DW_AT_upper_bound, upper_bound))
{
// The DWARF 4 spec says, in [5.11 Subrange Type
// Entries]:
// We can deduce the upper_bound from the
// lower_bound and the number of elements of the
// array:
- if (size_t u = lower_bound + count)
+ if (int64_t u = lower_bound.get_signed_value() + count)
upper_bound = u - 1;
- if (upper_bound == 0 && count == 0)
+ if (upper_bound.get_unsigned_value() == 0 && count == 0)
// No upper_bound nor count was present on the DIE, this means
// the array is considered to have an infinite (or rather not
// known) size.
is_infinite = true;
}
- if (UINT64_MAX == upper_bound)
+ if (UINT64_MAX == upper_bound.get_unsigned_value())
{
- // Of the upper_bound size is the max of the integer value, then
+ // If the upper_bound size is the max of the integer value, then
// it most certainly means infinite size.
is_infinite = true;
- upper_bound = 0;
+ upper_bound.set_unsigned(0);
}
result.reset
// <array_type_def definitions>
// <array_type_def::subrange_type>
+
+// <array_type_def::subrante_type::bound_value>
+
+/// Default constructor of the @ref
+/// array_type_def::subrange_type::bound_value class.
+///
+/// Constructs an unsigned bound_value of value zero.
+array_type_def::subrange_type::bound_value::bound_value()
+ : s_(UNSIGNED_SIGNEDNESS)
+{
+ v_.unsigned_ = 0;
+}
+
+/// Initialize an unsigned bound_value with a given value.
+///
+/// @param v the initial bound value.
+array_type_def::subrange_type::bound_value::bound_value(uint64_t v)
+ : s_(UNSIGNED_SIGNEDNESS)
+{
+ v_.unsigned_ = v;
+}
+
+/// Initialize a signed bound_value with a given value.
+///
+/// @param v the initial bound value.
+array_type_def::subrange_type::bound_value::bound_value(int64_t v)
+ : s_(SIGNED_SIGNEDNESS)
+{
+ v_.signed_ = v;
+}
+
+/// Getter of the signedness (unsigned VS signed) of the bound value.
+///
+/// @return the signedness of the bound value.
+enum array_type_def::subrange_type::bound_value::signedness
+array_type_def::subrange_type::bound_value::get_signedness() const
+{return s_;}
+
+/// Setter of the signedness (unsigned VS signed) of the bound value.
+///
+/// @param s the new signedness of the bound value.
+void
+array_type_def::subrange_type::bound_value::set_signedness(enum signedness s)
+{ s_ = s;}
+
+/// Getter of the bound value as a signed value.
+///
+/// @return the bound value as signed.
+int64_t
+array_type_def::subrange_type::bound_value::get_signed_value() const
+{return v_.signed_;
+}
+
+/// Getter of the bound value as an unsigned value.
+///
+/// @return the bound value as unsigned.
+uint64_t
+array_type_def::subrange_type::bound_value::get_unsigned_value()
+{return v_.unsigned_;}
+
+/// Setter of the bound value as unsigned.
+///
+/// @param v the new unsigned value.
+void
+array_type_def::subrange_type::bound_value::set_unsigned(uint64_t v)
+{
+ s_ = UNSIGNED_SIGNEDNESS;
+ v_.unsigned_ = v;
+}
+
+/// Setter of the bound value as signed.
+///
+/// @param v the new signed value.
+void
+array_type_def::subrange_type::bound_value::set_signed(int64_t v)
+{
+ s_ = SIGNED_SIGNEDNESS;
+ v_.signed_ = v;
+}
+
+// </array_type_def::subrante_type::bound_value>
+
struct array_type_def::subrange_type::priv
{
- size_t lower_bound_;
- size_t upper_bound_;
+ bound_value lower_bound_;
+ bound_value upper_bound_;
type_base_wptr underlying_type_;
translation_unit::language language_;
bool infinite_;
- priv(size_t ub,
+ priv(bound_value ub,
translation_unit::language l = translation_unit::LANG_C11)
- : lower_bound_(0), upper_bound_(ub), language_(l), infinite_(false)
+ : upper_bound_(ub), language_(l), infinite_(false)
{}
- priv(size_t lb, size_t ub,
+ priv(bound_value lb, bound_value ub,
translation_unit::language l = translation_unit::LANG_C11)
: lower_bound_(lb), upper_bound_(ub), language_(l)
{}
- priv(size_t lb, size_t ub, const type_base_sptr &u,
+ priv(bound_value lb, bound_value ub, const type_base_sptr &u,
translation_unit::language l = translation_unit::LANG_C11)
: lower_bound_(lb), upper_bound_(ub), underlying_type_(u), language_(l)
{}
/// @param loc the source location where the type is defined.
array_type_def::subrange_type::subrange_type(const environment* env,
const string& name,
- size_t lower_bound,
- size_t upper_bound,
+ bound_value lower_bound,
+ bound_value upper_bound,
type_base_sptr& underlying_type,
const location& loc,
translation_unit::language l)
: type_or_decl_base(env),
- type_base(env, upper_bound - lower_bound, 0),
+ type_base(env,
+ upper_bound.get_unsigned_value()
+ - lower_bound.get_unsigned_value(),
+ 0),
decl_base(env, name, loc, ""),
priv_(new priv(lower_bound, upper_bound, underlying_type, l))
{}
/// @param l the language that generated this subrange.
array_type_def::subrange_type::subrange_type(const environment* env,
const string& name,
- size_t lower_bound,
- size_t upper_bound,
+ bound_value lower_bound,
+ bound_value upper_bound,
const location& loc,
translation_unit::language l)
: type_or_decl_base(env),
- type_base(env, upper_bound - lower_bound, 0),
+ type_base(env,
+ upper_bound.get_unsigned_value()
+ - lower_bound.get_unsigned_value(), 0),
decl_base(env, name, loc, ""),
priv_(new priv(lower_bound, upper_bound, l))
{}
/// @param the language that generated this type.
array_type_def::subrange_type::subrange_type(const environment* env,
const string& name,
- size_t upper_bound,
+ bound_value upper_bound,
const location& loc,
translation_unit::language l)
: type_or_decl_base(env),
- type_base(env, upper_bound, 0),
+ type_base(env, upper_bound.get_unsigned_value(), 0),
decl_base(env, name, loc, ""),
priv_(new priv(upper_bound, l))
{}
/// Getter of the upper bound of the subrange type.
///
/// @return the upper bound of the subrange type.
-size_t
+int64_t
array_type_def::subrange_type::get_upper_bound() const
-{return priv_->upper_bound_;}
+{return priv_->upper_bound_.get_signed_value();}
/// Getter of the lower bound of the subrange type.
///
/// @return the lower bound of the subrange type.
-size_t
+int64_t
array_type_def::subrange_type::get_lower_bound() const
-{return priv_->lower_bound_;}
+{return priv_->lower_bound_.get_signed_value();}
/// Setter of the upper bound of the subrange type.
///
/// @param ub the new value of the upper bound.
void
-array_type_def::subrange_type::set_upper_bound(size_t ub)
+array_type_def::subrange_type::set_upper_bound(int64_t ub)
{priv_->upper_bound_ = ub;}
/// Setter of the lower bound.
///
/// @param lb the new value of the lower bound.
void
-array_type_def::subrange_type::set_lower_bound(size_t lb)
+array_type_def::subrange_type::set_lower_bound(int64_t lb)
{priv_->lower_bound_ = lb;}
/// Getter of the length of the subrange type.
/// rather a non-known) size.
///
/// @return the length of the subrange type.
-size_t
+uint64_t
array_type_def::subrange_type::get_length() const
{
if (is_infinite())
return true;
}
+ if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
+ {
+ const array_type_def::subrange_type *ty2 = is_subrange_type(second);
+ if (!ty2)
+ return false;
+
+ if (ty1->get_upper_bound() != ty2->get_upper_bound()
+ || ty1->get_lower_bound() != ty2->get_lower_bound()
+ || ty1->get_language() != ty2->get_language()
+ || !types_have_similar_structure(ty1->get_underlying_type(),
+ ty2->get_underlying_type()))
+ return false;
+
+ return true;
+ }
+
if (const function_type* ty1 = is_function_type(first))
{
const function_type* ty2 = is_function_type(second);
// Note that DWARF would actually have a lower_bound of -1 for an
// array of length 0.
- size_t max_bound = 0;
+ array_type_def::subrange_type::bound_value max_bound;
+ array_type_def::subrange_type::bound_value min_bound;
if (!is_infinite)
if (length > 0)
- max_bound = length - 1;
+ max_bound.set_signed(length - 1);
array_type_def::subrange_sptr p
(new array_type_def::subrange_type(ctxt.get_environment(),
- name, 0, max_bound,
+ name, min_bound, max_bound,
underlying_type, loc));
p->is_infinite(is_infinite);
test-diff-pkg/nss-devel-3.23.0-1.0.fc23.x86_64.rpm \
test-diff-pkg/nss-devel-3.24.0-1.0.fc23.x86_64.rpm \
test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt \
+test-diff-pkg/GtkAda-debuginfo-2.24.2-29.fc29.x86_64.rpm \
+test-diff-pkg/GtkAda-debuginfo-2.24.2-30.fc30.x86_64.rpm \
+test-diff-pkg/GtkAda-devel-2.24.2-29.fc29.x86_64.rpm \
+test-diff-pkg/GtkAda-devel-2.24.2-30.fc30.x86_64.rpm \
+test-diff-pkg/GtkAda-gl-2.24.2-29.fc29.x86_64--2.24.2-30.fc30.x86_64-report-0.txt \
+test-diff-pkg/GtkAda-gl-2.24.2-29.fc29.x86_64.rpm \
+test-diff-pkg/GtkAda-gl-2.24.2-30.fc30.x86_64.rpm \
+test-diff-pkg/GtkAda-gl-debuginfo-2.24.2-29.fc29.x86_64.rpm \
+test-diff-pkg/GtkAda-gl-debuginfo-2.24.2-30.fc30.x86_64.rpm \
\
test-fedabipkgdiff/dbus-glib-0.104-3.fc23.x86_64.rpm \
test-fedabipkgdiff/dbus-glib-debuginfo-0.104-3.fc23.x86_64.rpm \
--- /dev/null
+================ changes of 'libgtkada_gl-2.24.so.2'===============
+ Functions changes summary: 0 Removed, 2 Changed (3 filtered out), 0 Added functions
+ Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+ Function symbols changes summary: 0 Removed, 0 Added function symbol not referenced by debug info
+ Variable symbols changes summary: 6 Removed, 6 Added variable symbols not referenced by debug info
+
+ 2 functions with some indirect sub-type change:
+
+ [C]'function void gl_h__glgentextures(const gdk__gl__gl_configs, const gl_h__gluint_vec___XUP)' at gl_h.adb:35:1 has some indirect sub-type changes:
+ parameter 2 of type 'const gl_h__gluint_vec___XUP' has sub-type changes:
+ in unqualified underlying type 'struct gl_h__gluint_vec___XUP' at gl_h.ads:57:1:
+ type size hasn't changed
+ 1 data member change:
+ type of 'gl_h__gluint_vec___XUP::gl_h__gluint_vec___XUB* gl_h__gluint_vec___XUP::P_BOUNDS' changed:
+ in pointed to type 'struct gl_h__gluint_vec___XUP::gl_h__gluint_vec___XUB' at gl_h.ads:57:1:
+ type size hasn't changed
+ 2 data member changes:
+ type of 'integer gl_h__gluint_vec___XUP::gl_h__gluint_vec___XUB::LB0' changed:
+ entity changed from 'integer' to '<range natural___XDLU_0__2147483647>[2147483648]'
+ type size changed from 32 to 2147483647 (in bits)
+
+ type of 'integer gl_h__gluint_vec___XUP::gl_h__gluint_vec___XUB::UB0' changed:
+ entity changed from 'integer' to '<range natural___XDLU_0__2147483647>[2147483648]'
+ type size changed from 32 to 2147483647 (in bits)
+
+
+
+ [C]'function gtk__glarea__gtk_glarea gtk__glarea__gtk_new(gtk__glarea__gtk_glarea, const gtk__glarea__attributes_array___XUP)' at gtk-glarea.adb:63:1 has some indirect sub-type changes:
+ parameter 2 of type 'const gtk__glarea__attributes_array___XUP' has sub-type changes:
+ in unqualified underlying type 'struct gtk__glarea__attributes_array___XUP' at gtk-glarea.ads:48:1:
+ type size hasn't changed
+ 1 data member change:
+ type of 'gtk__glarea__attributes_array___XUP::gtk__glarea__attributes_array___XUB* gtk__glarea__attributes_array___XUP::P_BOUNDS' changed:
+ in pointed to type 'struct gtk__glarea__attributes_array___XUP::gtk__glarea__attributes_array___XUB':
+ type size hasn't changed
+ 2 data member changes:
+ type of 'integer gtk__glarea__attributes_array___XUP::gtk__glarea__attributes_array___XUB::LB0' changed:
+ entity changed from 'integer' to '<range natural___XDLU_0__2147483647>[2147483648]'
+ type size changed from 32 to 2147483647 (in bits)
+
+ type of 'integer gtk__glarea__attributes_array___XUP::gtk__glarea__attributes_array___XUB::UB0' changed:
+ entity changed from 'integer' to '<range natural___XDLU_0__2147483647>[2147483648]'
+ type size changed from 32 to 2147483647 (in bits)
+
+
+
+
+ 6 Removed variable symbols not referenced by debug info:
+
+ gtk__glarea__C210s
+ gtk__glarea__gtk_glarea_recordB43s
+ gtk__glarea__gtk_glarea_recordE39s
+ gtk__glarea__gtk_glarea_recordH40s
+ gtk__glarea__gtk_glarea_recordR41s
+ gtk__glarea__gtk_glarea_recordR41s___UNC
+
+ 6 Added variable symbols not referenced by debug info:
+
+ gtk__glarea__C208s
+ gtk__glarea__gtk_glarea_recordB41s
+ gtk__glarea__gtk_glarea_recordE37s
+ gtk__glarea__gtk_glarea_recordH38s
+ gtk__glarea__gtk_glarea_recordR39s
+ gtk__glarea__gtk_glarea_recordR39s___UNC
+
+================ end of changes of 'libgtkada_gl-2.24.so.2'===============
+
"data/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt",
"output/test-diff-pkg/nss-3.23.0-1.0.fc23.x86_64-report-0.txt"
},
+ {
+ "data/test-diff-pkg/GtkAda-gl-2.24.2-29.fc29.x86_64.rpm",
+ "data/test-diff-pkg/GtkAda-gl-2.24.2-30.fc30.x86_64.rpm",
+ "--fail-no-dbg",
+ "",
+ "data/test-diff-pkg/GtkAda-debuginfo-2.24.2-29.fc29.x86_64.rpm, "
+ "data/test-diff-pkg/GtkAda-gl-debuginfo-2.24.2-29.fc29.x86_64.rpm",
+ "data/test-diff-pkg/GtkAda-debuginfo-2.24.2-30.fc30.x86_64.rpm, "
+ "data/test-diff-pkg/GtkAda-gl-debuginfo-2.24.2-30.fc30.x86_64.rpm",
+ "data/test-diff-pkg/GtkAda-devel-2.24.2-29.fc29.x86_64.rpm",
+ "data/test-diff-pkg/GtkAda-devel-2.24.2-30.fc30.x86_64.rpm",
+ "data/test-diff-pkg/GtkAda-gl-2.24.2-29.fc29.x86_64--2.24.2-30.fc30.x86_64-report-0.txt",
+ "output/test-diff-pkg/GtkAda-gl-2.24.2-29.fc29.x86_64--2.24.2-30.fc30.x86_64-report-0.txt"
+ },
#endif //WITH_RPM
#ifdef WITH_DEB