[cfe-commits] r99806 - in /cfe/trunk: lib/AST/DeclCXX.cpp test/SemaCXX/warn-reorder-ctor-initialization.cpp
Daniel Dunbar
daniel at zuster.org
Tue Mar 30 20:13:37 PDT 2010
Hey Anders,
On Sun, Mar 28, 2010 at 10:13 PM, Anders Carlsson <andersca at mac.com> wrote:
> Author: andersca
> Date: Mon Mar 29 00:13:12 2010
> New Revision: 99806
>
> URL: http://llvm.org/viewvc/llvm-project?rev=99806&view=rev
> Log:
> Fix a nasty bug in the virtual base computation which would lead to us initializing virtual bases in the wrong order.
>
> Modified:
> cfe/trunk/lib/AST/DeclCXX.cpp
> cfe/trunk/test/SemaCXX/warn-reorder-ctor-initialization.cpp
>
> Modified: cfe/trunk/lib/AST/DeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=99806&r1=99805&r2=99806&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/DeclCXX.cpp (original)
> +++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Mar 29 00:13:12 2010
> @@ -83,9 +83,11 @@
> if (data().Bases)
> C.Deallocate(data().Bases);
>
> - int vbaseCount = 0;
> - llvm::SmallVector<const CXXBaseSpecifier*, 8> UniqueVbases;
> - bool hasDirectVirtualBase = false;
> + // The set of seen virtual base types.
> + llvm::SmallPtrSet<QualType, 8> SeenVBaseTypes;
> +
> + // The virtual bases of this class.
> + llvm::SmallVector<const CXXBaseSpecifier *, 8> VBases;
Can this use llvm::SetVector?
- Daniel
> data().Bases = new(C) CXXBaseSpecifier [NumBases];
> data().NumBases = NumBases;
> @@ -99,58 +101,44 @@
> continue;
> CXXRecordDecl *BaseClassDecl
> = cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl());
> - if (Base->isVirtual())
> - hasDirectVirtualBase = true;
> +
> + // Now go through all virtual bases of this base and add them.
> for (CXXRecordDecl::base_class_iterator VBase =
> BaseClassDecl->vbases_begin(),
> E = BaseClassDecl->vbases_end(); VBase != E; ++VBase) {
> - // Add this vbase to the array of vbases for current class if it is
> - // not already in the list.
> - // FIXME. Note that we do a linear search as number of such classes are
> - // very few.
> - int i;
> - for (i = 0; i < vbaseCount; ++i)
> - if (UniqueVbases[i]->getType() == VBase->getType())
> - break;
> - if (i == vbaseCount) {
> - UniqueVbases.push_back(VBase);
> - ++vbaseCount;
> - }
> + // Add this base if it's not already in the list.
> + if (SeenVBaseTypes.insert(VBase->getType()))
> + VBases.push_back(VBase);
> }
> - }
> - if (hasDirectVirtualBase) {
> - // Iterate one more time through the direct bases and add the virtual
> - // base to the list of vritual bases for current class.
> - for (unsigned i = 0; i < NumBases; ++i) {
> - const CXXBaseSpecifier *VBase = Bases[i];
> - if (!VBase->isVirtual())
> - continue;
> - int j;
> - for (j = 0; j < vbaseCount; ++j)
> - if (UniqueVbases[j]->getType() == VBase->getType())
> - break;
> - if (j == vbaseCount) {
> - UniqueVbases.push_back(VBase);
> - ++vbaseCount;
> - }
> +
> + if (Base->isVirtual()) {
> + // Add this base if it's not already in the list.
> + if (SeenVBaseTypes.insert(BaseType))
> + VBases.push_back(Base);
> }
> +
> }
> - if (vbaseCount > 0) {
> - // build AST for inhireted, direct or indirect, virtual bases.
> - data().VBases = new (C) CXXBaseSpecifier [vbaseCount];
> - data().NumVBases = vbaseCount;
> - for (int i = 0; i < vbaseCount; i++) {
> - QualType QT = UniqueVbases[i]->getType();
> - // Skip dependent types; we can't do any checking on them now.
> - if (QT->isDependentType())
> - continue;
> - CXXRecordDecl *VBaseClassDecl
> - = cast<CXXRecordDecl>(QT->getAs<RecordType>()->getDecl());
> - data().VBases[i] =
> - CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true,
> - VBaseClassDecl->getTagKind() == RecordDecl::TK_class,
> - UniqueVbases[i]->getAccessSpecifier(), QT);
> - }
> +
> + if (VBases.empty())
> + return;
> +
> + // Create base specifier for any direct or indirect virtual bases.
> + data().VBases = new (C) CXXBaseSpecifier[VBases.size()];
> + data().NumVBases = VBases.size();
> + for (int I = 0, E = VBases.size(); I != E; ++I) {
> + QualType VBaseType = VBases[I]->getType();
> +
> + // Skip dependent types; we can't do any checking on them now.
> + if (VBaseType->isDependentType())
> + continue;
> +
> + CXXRecordDecl *VBaseClassDecl
> + = cast<CXXRecordDecl>(VBaseType->getAs<RecordType>()->getDecl());
> +
> + data().VBases[I] =
> + CXXBaseSpecifier(VBaseClassDecl->getSourceRange(), true,
> + VBaseClassDecl->getTagKind() == RecordDecl::TK_class,
> + VBases[I]->getAccessSpecifier(), VBaseType);
> }
> }
>
>
> Modified: cfe/trunk/test/SemaCXX/warn-reorder-ctor-initialization.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-reorder-ctor-initialization.cpp?rev=99806&r1=99805&r2=99806&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/warn-reorder-ctor-initialization.cpp (original)
> +++ cfe/trunk/test/SemaCXX/warn-reorder-ctor-initialization.cpp Mon Mar 29 00:13:12 2010
> @@ -87,3 +87,15 @@
> union {int a,b;};
> Anon3() : b(1) {}
> };
> +
> +namespace T1 {
> +
> +struct S1 { };
> +struct S2: virtual S1 { };
> +struct S3 { };
> +
> +struct S4: virtual S3, S2 {
> + S4() : S2(), // expected-warning {{base class 'T1::S2' will be initialized after}}
> + S3() { }; // expected-note {{base 'T1::S3'}}
> +};
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list