diff options
-rw-r--r-- | lib/AST/DeclCXX.cpp | 6 | ||||
-rw-r--r-- | test/CodeGenCXX/virtual-bases.cpp | 23 |
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() { } + +} |