struct base {
virtual void vcall() = 0;
};
struct foo final : base {
void vcall() final;
};
void call_base(base& b) {
b.vcall();
}
void call_foo(foo& f) {
call_base(f);
}
void call_foo_directly(foo& f) {
f.vcall();
}
clang 16 produces:
call_base(base&):
mov rax, qword ptr [rdi]
jmp qword ptr [rax]
call_foo(foo&):
mov rax, qword ptr [rdi]
jmp qword ptr [rax]
call_foo_directly(foo&):
jmp foo::vcall()@PLT
GCC and MSVC produce the same result, so it's not a problem limited to clang.
Shouldn't it be possible for call_foo
to contain a non-virtual call to foo::vcall()
too?
Is this a missed optimization, or is it possible for the call to be virtual?
foo
might be final, other thing can derive frombase
– Maggotycall_base
intocall_foo
? The compiler is clearly able to make this optimization locally. – Rateablebase& b = f; b.vcall()
but does devirtualize((base&) f).vcall()
, seems like a missed optimization. – Beaty