[clang] [clang-repl] fix vtable symbol duplication error (closes #141039) (PR #185648)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 10 06:36:58 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
@llvm/pr-subscribers-clang-codegen
Author: None (conrade-ctc)
<details>
<summary>Changes</summary>
In incremental mode, emit by ExternalLinkage causes duplicate symbol error. A single targeted change in getVTableLinkage() fixes the issue by returning LinkOnceODRLinkage when IncrementalExtensions is active. The JIT linker then keeps the first definition a silently discards subsequent ones.
closes issue #<!-- -->141039
---
Full diff: https://github.com/llvm/llvm-project/pull/185648.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/CGVTables.cpp (+8)
- (added) clang/test/Interpreter/virtualdef-outside.cpp (+19)
``````````diff
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index 3891697a986e4..cadc98169226a 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -1151,6 +1151,14 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) {
? llvm::GlobalVariable::LinkOnceODRLinkage
: llvm::Function::InternalLinkage;
+ // In incremental compilation, each partial translation unit is a separate
+ // LLVM module. Multiple PTUs may independently emit the vtable (once the
+ // key function's body is visible), causing duplicate symbol errors in the
+ // JIT. Use linkonce_odr so the JIT linker keeps the first definition and
+ // silently discards the rest, matching how template vtables work.
+ if (Context.getLangOpts().IncrementalExtensions)
+ return llvm::GlobalVariable::LinkOnceODRLinkage;
+
return llvm::GlobalVariable::ExternalLinkage;
case TSK_ImplicitInstantiation:
diff --git a/clang/test/Interpreter/virtualdef-outside.cpp b/clang/test/Interpreter/virtualdef-outside.cpp
new file mode 100644
index 0000000000000..fbb232ad68a8c
--- /dev/null
+++ b/clang/test/Interpreter/virtualdef-outside.cpp
@@ -0,0 +1,19 @@
+// REQUIRES: host-supports-jit
+// RUN: cat %s | clang-repl | FileCheck %s
+// virtual functions defined outside of class had duplicate symbols:
+// duplicate definition of symbol '__ZTV3Two' (i.e., vtable for Two)
+// see https://github.com/llvm/llvm-project/issues/141039.
+// fixed in PR: XXX
+
+extern "C" int printf(const char *, ...);
+
+struct One { virtual void print() { printf("ONE\n"); } };
+One().print();
+// CHECK: ONE
+
+struct Two { virtual void print(); };
+void Two::print() { printf("TWO\n"); }
+Two().print();
+// CHECK: TWO
+
+%quit
``````````
</details>
https://github.com/llvm/llvm-project/pull/185648
More information about the cfe-commits
mailing list