[llvm-branch-commits] [clang] [clang][CodeGen] Identify virtual methods by their override chain root in the call graph section (PR #230831)
Eli Friedman via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Oct 11 12:05:48 PDT 2026
================
@@ -0,0 +1,87 @@
+// Tests that virtual calls through a pointer to any class of a hierarchy get
+// the same call graph section type identifier as the overriders they can reach,
+// even when the overriders have a covariant return type.
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -fexperimental-call-graph-section \
+// RUN: -std=c++17 -emit-llvm -o - %s | FileCheck %s
+
+////////////////////////////////////////////////////////////////////////////////
+// A chain of covariant overrides: all methods are identified by the type of
+// Base::clone, the method that introduced the virtual function.
+
+struct Base {
+ virtual ~Base() {}
+ virtual Base *clone() { return this; }
+};
+
+struct Mid : Base {
+ Mid *clone() override { return this; }
+};
+
+struct Derived : Mid {
+ Derived *clone() override { return this; }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// A method overriding two virtual functions with different covariant return
+// types: the method is identified after the first one (A::f), and the return
+// adjusting thunk that fills the vtable slot of B::f after the second one.
----------------
efriedma-quic wrote:
This is sort of confusing two different concepts. Consider:
```c++
struct A1 { };
struct B1 {};
struct C1 : A1, B1 {};
struct A2 {
virtual A1 *f() { return nullptr; }
};
struct B2 {
virtual B1 *f() { return nullptr; }
};
struct C2 : A2, B2 {
C1 *f() override { return nullptr; }
};
```
There is no return adjustment in this case: casting between A1/B1/C1 is a no-op because both bases are at offset zero.
I guess the actual rule here is the method inherits its callgraph metadata from the primary base class? I guess that works, but I'm not sure `*MD->begin_overridden_methods()` is guaranteed to return the right method; the Itanium ABI has its own rule for computing the primary base class.
https://github.com/llvm/llvm-project/pull/230831
More information about the llvm-branch-commits
mailing list