From e8bf5b803c44d7ec40f9659295a5d9f1e3feefcb Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Tue, 19 May 2020 11:49:43 +0200 Subject: [PATCH] Bug 25989 - type_topo_comp doesn't meet irreflexive requirements 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 --- 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); } -- 2.43.5