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

[Bug default/20476] abidiff doesn't report incompatibility for abstract class when implementation has hidden visibility



https://sourceware.org/bugzilla/show_bug.cgi?id=20476

dodji at redhat dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2016-08-25
     Ever confirmed|0                           |1

--- Comment #3 from dodji at redhat dot com ---
I confirm this issue.  It's a real and an interesting one to tackle :-)

The bottom line of the problem is that when two types (classes) are compared by
libabigail, the comparison engine doesn't compare their virtual member
functions as part of the type-comparison process.

Changes in a virtual member functions (including changes in their vtable index)
are detected when comparing member functions themselves, just like when
libabigail compares any other function.  But that happens only if the member
function is publicly exported by the binary.

In the test test case you reported, the member functions of the Interface class
are not defined; they are just declared (because they are pure virtual).  So
when the comparison engine compares the two functions "Interface*
make_interface()", it compares the two 'Interface' types and sees no change
because the member functions of the Interface type are not compared.

The virtual member function addition to the "Interface" type can be indirectly
detected by comparing the member function of the "Implementation" class that
inherits the class "Interface" and *defines* its virtual member function. But
for that to happen those virtual member functions have to be publicly exported
by the binary for libabigail to take it into account.

So when the member functions of the "Implementation" class are not exported by
the binary, libabigail's comparison engine doesn't report the change.

Now the reason why libabigail doesn't compare virtual member functions when it
compares two class types is that in the debug info emitted by GCC (at least)
there are cases when the information about virtual member functions is just not
present, for debug-info size optimization purposes :(

Imagine that a class "Interface" is declared in a header file foo.h.  Imagine
that foo.h is included in several translation units and that the object files
resulting from those translation units are linked together to produce a shared
library.

In that case, generally speaking, the debug info that describes the virtual
member of the "Interface" class is going to be emitted only in the object file
resulting from the translation unit that *defines* the first non-pure virtual
member function of the "Interface" class.

The debug info for the "Interface" class as read from the other translation
units in the same binary will *NOT* contain any information about its virtual
member functions.

So if virtual member functions are taken into account when comparing the
"Interface" class types then there are chances that the comparison engine says
that the types are different (because of them has virtual member functions
while the other doesn't) when they really are not.

In other words, taking virtual member functions into account when comparing
class types can lead to spurious change reports.

===============================

That being said, I believe we need to support the use case you just reported. 
So we need to overcome the difficulties I exposed above.

One approach could be to "de-duplicate" type definitions that we read from the
debug info.  This means that when we build the internal representation (IR) for
a given type, *IF* there already is an IR for that type, we need to re-use that
existing IR rather than building a new one.  Re-using implies to potentially
"augment" the existing IR with additional information that we are reading from
the debug info.

By doing this, we'd have just one IR for the "Interface" class type in the
binary, even if that class type was declared in several translation units.  And
that IR would be assured to have the information for its virtual member
functions.  At that point, we'll make the comparison engine take virtual member
functions into account when comparing two class types.

-- 
You are receiving this mail because:
You are on the CC list for the bug.