aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2010-05-25 00:33:13 +0000
committerDaniel Dunbar <daniel@zuster.org>2010-05-25 00:33:13 +0000
commitb9aefa775158b68c453e4ac0e4e2ada561900d26 (patch)
tree1a6a04296978a60e548a8931a68c9bfb623fc3bf
parente669f89e613029d4e21869b90f6d3f6cd299ff2a (diff)
IRgen/C++: When mark vtables used, make sure to still append to the VTableUse array if we promote a vtable from being just used to having its definition required. This ensures that we properly inform the consumer about whether the vtable is required or not, previously we could fail to do so when the vtable was in the VTableUses array before the decl which marked it as required.
- I think this can be cleaned up, since this means we may notify the consumer about the vtable twice, but I didn't see an easy fix for this without more substantial refactoring. - Doug, please review! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104577 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaDeclCXX.cpp11
-rw-r--r--test/CodeGenCXX/vtable-linkage.cpp16
2 files changed, 24 insertions, 3 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index d2655cb625..60f3fe9283 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -6085,8 +6085,15 @@ void Sema::MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,
std::pair<llvm::DenseMap<CXXRecordDecl *, bool>::iterator, bool>
Pos = VTablesUsed.insert(std::make_pair(Class, DefinitionRequired));
if (!Pos.second) {
- Pos.first->second = Pos.first->second || DefinitionRequired;
- return;
+ // If we already had an entry, check to see if we are promoting this vtable
+ // to required a definition. If so, we need to reappend to the VTableUses
+ // list, since we may have already processed the first entry.
+ if (DefinitionRequired && !Pos.first->second) {
+ Pos.first->second = true;
+ } else {
+ // Otherwise, we can early exit.
+ return;
+ }
}
// Local classes need to have their virtual members marked
diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp
index 02b1d5c748..b3b68703c6 100644
--- a/test/CodeGenCXX/vtable-linkage.cpp
+++ b/test/CodeGenCXX/vtable-linkage.cpp
@@ -160,4 +160,18 @@ void use_F(F<char> &fc) {
// CHECK-12: @_ZTSN12_GLOBAL__N_11AE = internal constant
// CHECK-12: @_ZTIN12_GLOBAL__N_11AE = internal constant
-
+// RUN: FileCheck --check-prefix=CHECK-G %s < %t
+//
+// CHECK-G: @_ZTV1GIiE = weak_odr constant
+template <typename T>
+class G {
+public:
+ G() {}
+ virtual void f0();
+ virtual void f1();
+};
+template <>
+void G<int>::f1() {}
+template <typename T>
+void G<T>::f0() {}
+void G_f0() { new G<int>(); }