[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Bug 22075 data_member_diff_comp comparison functor isn't a total ordering.



Hey Mark,

OK, so I have committed your patch, slightly edited, to the master
branch.

Below is what hit the repository in the end.

Thanks again for looking into this.

Cheers,

>From 60a4743af492ba1f00adece30a9c5e34d5fd1b42 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mark@klomp.org>
Date: Mon, 11 Sep 2017 22:50:22 +0200
Subject: [PATCH 1/3] Bug 22075 - data_member_diff_comp forgets data members
 names

This patch makes the data_member_diff_comp comparison functor consider
all the properties local to the data member: that is, its offset and
its name.

It used to only take the offset into account.

This makes sure that offset change reports have a stable ordering and
thus makes the runtestdiffpkg testcase succeeds on debian-i386.

	* src/abg-comparison.cc (data_member_diff_comp): Make the
	comparison take the qualified name of the data member into
	account.  Also, if the initial offset and qualified names of the
	data members of the diff nodes are equal, consider the offset and
	qualified names of the new data members.

Signed-off-by: Mark Wielaard <mark@klomp.org>
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
---
 src/abg-comparison.cc | 45 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 42 insertions(+), 3 deletions(-)

diff --git a/src/abg-comparison.cc b/src/abg-comparison.cc
index 8747e0c..9580509 100644
--- a/src/abg-comparison.cc
+++ b/src/abg-comparison.cc
@@ -6730,8 +6730,10 @@ sort_string_base_diff_sptr_map(const string_base_diff_sptr_map& map,
 }
 
 /// A comparison functor to compare two instances of @ref var_diff
-/// that represent changed data members based on the offset of their
-/// initial value.
+/// that represent changed data members based on the offset of the
+/// initial data members, or if equal, based on their qualified name.
+/// If equal again, then the offset and qualified name of the new data
+/// members are considered.
 struct data_member_diff_comp
 {
   /// @param f the first change to data member to take into account
@@ -6749,7 +6751,44 @@ struct data_member_diff_comp
     assert(is_data_member(first_dm));
     assert(is_data_member(second_dm));
 
-    return get_data_member_offset(first_dm) < get_data_member_offset(second_dm);
+    size_t off1 = get_data_member_offset(first_dm);
+    size_t off2 = get_data_member_offset(second_dm);
+
+    if (off1 != off2)
+      return off1 < off2;
+
+    // The two offsets of the initial data members are the same.  So
+    // lets compare the qualified name of these initial data members.
+
+    string name1 = first_dm->get_qualified_name();
+    string name2 = second_dm->get_qualified_name();
+
+    if (name1 != name2)
+      return name1 < name2;
+
+    // The offsets and the qualified names of the initial data members
+    // are the same.  Let's now compare the offsets of the *new* data
+    // members.
+
+    first_dm = f->second_var();
+    second_dm = s->second_var();
+
+    assert(is_data_member(first_dm));
+    assert(is_data_member(second_dm));
+
+    off1 = get_data_member_offset(first_dm);
+    off2 = get_data_member_offset(second_dm);
+
+    if (off1 != off2)
+      return off1 < off2;
+
+    // The offsets of the new data members are the same, dang!  Let's
+    // compare the qualified names of these new data members then.
+
+    name1 = first_dm->get_qualified_name();
+    name2 = second_dm->get_qualified_name();
+
+    return name1 < name2;
   }
 }; // end struct var_diff_comp
 
-- 
1.8.3.1

-- 
		Dodji