summaryrefslogtreecommitdiffstats
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
commite47380fb193ec4db782990400197debb745ad3fe (patch)
treea5963b885b85bbffd1d995296afba4837cbf4d90
parentac031880affc08f529c1f67d891d6b64c4be44cd (diff)
downloadbcm5719-llvm-e47380fb193ec4db782990400197debb745ad3fe.tar.gz
bcm5719-llvm-e47380fb193ec4db782990400197debb745ad3fe.zip
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.
llvm-svn: 99829
-rw-r--r--clang/lib/AST/DeclCXX.cpp6
-rw-r--r--clang/test/CodeGenCXX/virtual-bases.cpp23
2 files changed, 26 insertions, 3 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 3b3bf1ba443..ed02edd3944 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/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/clang/test/CodeGenCXX/virtual-bases.cpp b/clang/test/CodeGenCXX/virtual-bases.cpp
index 62771757630..61de3153fd5 100644
--- a/clang/test/CodeGenCXX/virtual-bases.cpp
+++ b/clang/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() { }
+
+}
OpenPOWER on IntegriCloud