aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-03-29 19:49:09 +0000
committerAnders Carlsson <andersca@mac.com>2010-03-29 19:49:09 +0000
commit1c3639351f8c252ddcc13d234cabf8780b1c235f (patch)
treefd3e30d712ac8bdd785d675c11f540b43da48667
parenta1d2d397d64a9791f609532c995ad3eb9158d203 (diff)
When collecting virtual bases it's very important to use the canonical type of the base class. Otherwise, we might add the same virtual base class twice if the virtual base is an instantiated template. Fixes PR6251.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99829 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/DeclCXX.cpp6
-rw-r--r--test/CodeGenCXX/virtual-bases.cpp23
2 files changed, 26 insertions, 3 deletions
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 3b3bf1ba44..ed02edd394 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -84,7 +84,7 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
C.Deallocate(data().Bases);
// The set of seen virtual base types.
- llvm::SmallPtrSet<QualType, 8> SeenVBaseTypes;
+ llvm::SmallPtrSet<CanQualType, 8> SeenVBaseTypes;
// The virtual bases of this class.
llvm::SmallVector<const CXXBaseSpecifier *, 8> VBases;
@@ -107,13 +107,13 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
BaseClassDecl->vbases_begin(),
E = BaseClassDecl->vbases_end(); VBase != E; ++VBase) {
// Add this base if it's not already in the list.
- if (SeenVBaseTypes.insert(VBase->getType()))
+ if (SeenVBaseTypes.insert(C.getCanonicalType(VBase->getType())))
VBases.push_back(VBase);
}
if (Base->isVirtual()) {
// Add this base if it's not already in the list.
- if (SeenVBaseTypes.insert(BaseType))
+ if (SeenVBaseTypes.insert(C.getCanonicalType(BaseType)))
VBases.push_back(Base);
}
diff --git a/test/CodeGenCXX/virtual-bases.cpp b/test/CodeGenCXX/virtual-bases.cpp
index 6277175763..61de3153fd 100644
--- a/test/CodeGenCXX/virtual-bases.cpp
+++ b/test/CodeGenCXX/virtual-bases.cpp
@@ -23,3 +23,26 @@ struct C : virtual A {
// CHECK: define void @_ZN1CC1Eb(%struct.B* %this, i1 zeroext)
// CHECK: define void @_ZN1CC2Eb(%struct.B* %this, i8** %vtt, i1 zeroext)
C::C(bool) { }
+
+// PR6251
+namespace PR6251 {
+
+// Test that we don't call the A<char> constructor twice.
+
+template<typename T>
+struct A { A(); };
+
+struct B : virtual A<char> { };
+struct C : virtual A<char> { };
+
+struct D : B, C {
+ D();
+};
+
+// CHECK: define void @_ZN6PR62511DC1Ev
+// CHECK: call void @_ZN6PR62511AIcEC2Ev
+// CHECK-NOT: call void @_ZN6PR62511AIcEC2Ev
+// CHECK: ret void
+D::D() { }
+
+}