diff options
author | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2023-06-14 12:45:34 +0800 |
---|---|---|
committer | Chuanqi Xu <yedeng.yd@linux.alibaba.com> | 2023-06-14 12:45:34 +0800 |
commit | d8a36b00d198fdc2ea866ea5da449628db07070f (patch) | |
tree | 7438ab2bdde0bef1cbca079f176edc4d91379c91 /clang/lib/CodeGen/CGVTables.cpp | |
parent | bd96d7b81f457c16d3bced596ab3cf095f8fb101 (diff) | |
download | llvm-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.cpp | 9 |
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 |