Bug 25989 - type_topo_comp doesn't meet irreflexive requirements

Message ID 87a7248a8l.fsf@seketeli.org
State Committed
Series Bug 25989 - type_topo_comp doesn't meet irreflexive requirements |

Commit Message

Dodji Seketeli May 19, 2020, 10:55 a.m. UTC

When emitting abixml types inside a given scope are sorted
topologically.  Types that don't have source definition location
information are sorted lexicographically.

There are certain types however that need more careful consideration.

Those are empty-qualified types.  That is, qualified types (like
cv-qualified types) that carry no qualifier.  The patch explains
in-extenso in comments where those types come from.  You can also look
at the comments of the function maybe_strip_qualification for even
more context.

Simply put, an empty qualified type like 'NONE reference type' equals it's
non-qualified variant 'reference type'.

During the topological sorting, we chose to have the empty-qualified
variant "come before" (i.e, be "less than") the non-qualified variant.
This is alright.

The bug however is that we failed to handle the case were we are
looking at two empty-qualified types that are equal.  In that case, of
course, they are meant to be topologically equivalent.

Fixed thus.

	* src/abg-ir.cc (type_topo_comp::operator()): In the comparison
	operator consider two equivalent empty-qualified types as being
	topologically equivalent.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>

Applied to master.

 src/abg-ir.cc | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)


diff --git a/src/abg-ir.cc b/src/abg-ir.cc
index aefbd086..5cc39f59 100644
--- a/src/abg-ir.cc
+++ b/src/abg-ir.cc
@@ -2740,7 +2740,32 @@  struct type_topo_comp
 	if (s1 == s2)
 	  if (qualified_type_def * q = is_qualified_type(f))
 	    if (q->get_cv_quals() == qualified_type_def::CV_NONE)
-	      return true;
+	      if (!is_qualified_type(s))
+		// We are looking at two types that are the result of
+		// an optimization that happens during the IR
+		// construction.  Namely, type f is a cv-qualified
+		// type with no qualifier (no const, no volatile, no
+		// nothing, we call it an empty-qualified type).
+		// These are the result of an optimization which
+		// removes "redundant qualifiers" from some types.
+		// For instance, consider a "const reference".  The
+		// const there is redundant because a reference is
+		// always const.  So as a result of the optimizaton
+		// that type is going to be transformed into an
+		// empty-qualified reference. If we don't make that
+		// optimization, then we risk having spurious change
+		// reports down the road.  But then, as a consequence
+		// of that optimization, we need to sort the
+		// empty-qualified type and its non-qualified variant
+		// e.g, to ensure stability in the abixml output; both
+		// types are logically equal, but here, we decide that
+		// the empty-qualified one is topologically "less
+		// than" the non-qualified counterpart.
+		//
+		// So here, type f is an empty-qualified type and type
+		// s is its non-qualified variant.  We decide that f
+		// is topologically less than s.
+		return true;
 	return (s1 < s2);