aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGVTables.cpp
diff options
context:
space:
mode:
authorChuanqi Xu <yedeng.yd@linux.alibaba.com>2023-06-14 12:45:34 +0800
committerChuanqi Xu <yedeng.yd@linux.alibaba.com>2023-06-14 12:45:34 +0800
commitd8a36b00d198fdc2ea866ea5da449628db07070f (patch)
tree7438ab2bdde0bef1cbca079f176edc4d91379c91 /clang/lib/CodeGen/CGVTables.cpp
parentbd96d7b81f457c16d3bced596ab3cf095f8fb101 (diff)
downloadllvm-d8a36b00d198fdc2ea866ea5da449628db07070f.zip
llvm-d8a36b00d198fdc2ea866ea5da449628db07070f.tar.gz
llvm-d8a36b00d198fdc2ea866ea5da449628db07070f.tar.bz2
[ABI] [C++20] [Modules] Don't generate vtable if the class is defined in other module unit
Close https://github.com/llvm/llvm-project/issues/61940. The root cause is that clang will generate vtable as strong symbol now even if the corresponding class is defined in other module units. After I check the wording in Itanium ABI, I find this is not inconsistent. Itanium ABI 5.2.3 (https://itanium-cxx-abi.github.io/cxx-abi/abi.html#vague-vtable) says: > The virtual table for a class is emitted in the same object containing > the definition of its key function, i.e. the first non-pure virtual > function that is not inline at the point of class definition. So the current behavior is incorrect. This patch tries to address this. Also I think we need to do a similar change for MSVC ABI. But I don't find the formal wording. So I don't address this in this patch. Reviewed By: rjmccall, iains, dblaikie Differential Revision: https://reviews.llvm.org/D150023
Diffstat (limited to 'clang/lib/CodeGen/CGVTables.cpp')
-rw-r--r--clang/lib/CodeGen/CGVTables.cpp9
1 files changed, 8 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index 32259d1..fb0276a 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -1172,9 +1172,16 @@ bool CodeGenVTables::isVTableExternal(const CXXRecordDecl *RD) {
if (!keyFunction)
return false;
+ const FunctionDecl *Def;
// Otherwise, if we don't have a definition of the key function, the
// vtable must be defined somewhere else.
- return !keyFunction->hasBody();
+ if (!keyFunction->hasBody(Def))
+ return true;
+
+ assert(Def && "The body of the key function is not assigned to Def?");
+ // If the non-inline key function comes from another module unit, the vtable
+ // must be defined there.
+ return Def->isInAnotherModuleUnit() && !Def->isInlineSpecified();
}
/// Given that we're currently at the end of the translation unit, and