Could key functions be used to reason about availability of inline method definitions?

I was poking around some object files and noticed function definitions
that seemed unnecessary. They were for inline functions not actually
used in the file except by reference from a vtable.

For example:

  struct Rectangle {
    virtual int colour() { return 1; }
    virtual void draw();
  };

  struct Square : public Rectangle {
    virtual void draw() override;
  };

  void Square::draw() {}

Both Clang and GCC will emit a definition of Rectangle::colour() here
because it's referenced by Square's vtable which we must define, and
it's an inline function so we don't know if it's defined anywhere
else.

But, don't we actually know it's defined elsewhere? Since Rectangle
has a key function, its vtable will be defined elsewhere. That vtable
will reference Rectangle::colour(), so that too must have a definition
elsewhere. Could we use this reasoning to omit the definition of
colour() in the current TU, or at least mark it available_externally?

I'm thinking exploiting this could allow the compiler to emit a bit
less code. Or is there something I'm missing?

Cheers,
Hans

Nothing immediately jumps out at me as making this invalid… (but I have a nagging feeling that there probably is an issue and I’m likely missing it - I imagine Richard Smith (CC’d), John McCall, etc, would be more likely to spot the nuances here)

Theoretically, there is no requirement that a symbol for Rectangle::colour be provided by the object file with the key function. In practice I’d expect the symbol would probably be provided anyway, but I think this would formally be a new ABI requirement.

There might also be symbol visibility issues (eg with -fvisibility-inlines-hidden).

Theoretically, there is no requirement that a symbol for Rectangle::colour be provided by the object file with the key function. In practice I’d expect the symbol would probably be provided anyway, but I think this would formally be a new ABI requirement.

Right. It’s not an unreasonable requirement — at least if it comes with a guarantee that other translation units won’t emit those functions, so that the key-function translation unit can emit them as strong definitions — but it’s not one made by the ABI today.

There might also be symbol visibility issues (eg with -fvisibility-inlines-hidden).

Yeah, this is probably the biggest practical problem that would come up.

John.

Sounds like a great idea to experiment with, maybe behind a flag.

I’ll note that Windows doesn’t have key functions and that it’d be nice to have something like this there too. https://bugs.llvm.org/show_bug.cgi?id=33628 has some discussions about this (maybe we just want a /Zc:keyFunctions thingy for clang-cl).