[clang] [clang] Check inline defs when emitting speculative vtable (PR #100785)
Fabian Parzefall via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 28 12:22:19 PDT 2024
https://github.com/FPar updated https://github.com/llvm/llvm-project/pull/100785
>From 13f60e1835c2a5876fa873fc5b4087f942a90316 Mon Sep 17 00:00:00 2001
From: Fabian Parzefall <parzefall at meta.com>
Date: Fri, 26 Jul 2024 10:46:22 -0700
Subject: [PATCH] [clang] Check inline defs when emitting speculative vtable
Clang should only emit an available_externally vtable when there are no
unused virtual inline functions. Currently, if such such a function is
declared without inline inside the class, but is defined inline outside
the class, Clang might emit the vtable as available_externally. This
happens because Clang only considers the declarations of vtable entries,
but not the definitions. This patch addresses this by inspecting the
definitions in addition to the declarations.
---
clang/lib/CodeGen/ItaniumCXXABI.cpp | 5 +++-
.../vtable-available-externally.cpp | 25 +++++++++++++------
2 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 0cde8a192eda08..c9aed292d4e5d1 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -442,7 +442,10 @@ class ItaniumCXXABI : public CodeGen::CGCXXABI {
continue;
const CXXMethodDecl *Method = VtableComponent.getFunctionDecl();
- if (!Method->getCanonicalDecl()->isInlined())
+ const FunctionDecl *FD = Method->getDefinition();
+ const bool IsInlined =
+ Method->getCanonicalDecl()->isInlined() || (FD && FD->isInlined());
+ if (!IsInlined)
continue;
StringRef Name = CGM.getMangledName(VtableComponent.getGlobalDecl());
diff --git a/clang/test/CodeGenCXX/vtable-available-externally.cpp b/clang/test/CodeGenCXX/vtable-available-externally.cpp
index a57eb39edfe102..ab105260bc75aa 100644
--- a/clang/test/CodeGenCXX/vtable-available-externally.cpp
+++ b/clang/test/CodeGenCXX/vtable-available-externally.cpp
@@ -250,28 +250,39 @@ struct C : A {
virtual void car();
};
+// Inline definition outside body, so we can't emit vtable available_externally
+// (see previous).
+// CHECK-TEST10-DAG: @_ZTVN6Test101FE = external unnamed_addr constant
+struct F : A {
+ void foo();
+ virtual void cat(); // inline outside body
+};
+inline void F::cat() {}
+
// no key function, vtable will be generated everywhere it will be used
// CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
struct E : A {};
-void g(A& a) {
+void h(A& a) {
a.foo();
a.bar();
}
-void f() {
+void g() {
A a;
- g(a);
+ h(a);
B b;
- g(b);
+ h(b);
C c;
- g(c);
+ h(c);
D d;
- g(d);
+ h(d);
E e;
- g(e);
+ h(e);
+ F f;
+ h(f);
}
} // Test10
More information about the cfe-commits
mailing list