On Thu, Jun 12, 2014 at 12:49 PM, Reid Kleckner <[email protected]> wrote:
> Author: rnk > Date: Thu Jun 12 14:49:17 2014 > New Revision: 210813 > > URL: http://llvm.org/viewvc/llvm-project?rev=210813&view=rev > Log: > MS ABI: Fix forming pointers to members of a base class > > Previously we would calculate the inheritance model of a class when > requiring a pointer to member type of that class to be complete. The > inheritance model is used to figure out how many fields are used by the > member pointer. > > However, once we require a pointer to member of a derived class type to > be complete, we can form pointers to members of bases without > calculating the inheritance model for those bases. This was causing > crashes on this simple test case: > > struct A { > void f(); > void f(int); > }; > struct B : public A {}; > void g() { void (B::*a)() = &B::f; } > > Now we calculate the inheritance models of all base classes when > completing a member pointer type. > > Fixes PR2007. > PR20007 (one more 0), right? (Also in the test) > > Modified: > cfe/trunk/lib/Sema/SemaType.cpp > cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp > > Modified: cfe/trunk/lib/Sema/SemaType.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=210813&r1=210812&r2=210813&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaType.cpp (original) > +++ cfe/trunk/lib/Sema/SemaType.cpp Thu Jun 12 14:49:17 2014 > @@ -5147,6 +5147,45 @@ static bool hasVisibleDefinition(Sema &S > return LookupResult::isVisible(S, D); > } > > +/// Locks in the inheritance model for the given class and all of its > bases. > +static void assignInheritanceModel(Sema &S, CXXRecordDecl *RD) { > + RD = RD->getMostRecentDecl(); > + if (!RD->hasAttr<MSInheritanceAttr>()) { > + MSInheritanceAttr::Spelling IM; > + > + switch (S.MSPointerToMemberRepresentationMethod) { > + case LangOptions::PPTMK_BestCase: > + IM = RD->calculateInheritanceModel(); > + break; > + case LangOptions::PPTMK_FullGeneralitySingleInheritance: > + IM = MSInheritanceAttr::Keyword_single_inheritance; > + break; > + case LangOptions::PPTMK_FullGeneralityMultipleInheritance: > + IM = MSInheritanceAttr::Keyword_multiple_inheritance; > + break; > + case LangOptions::PPTMK_FullGeneralityVirtualInheritance: > + IM = MSInheritanceAttr::Keyword_unspecified_inheritance; > + break; > + } > + > + RD->addAttr(MSInheritanceAttr::CreateImplicit( > + S.getASTContext(), IM, > + /*BestCase=*/S.MSPointerToMemberRepresentationMethod == > + LangOptions::PPTMK_BestCase, > + S.ImplicitMSInheritanceAttrLoc.isValid() > + ? S.ImplicitMSInheritanceAttrLoc > + : RD->getSourceRange())); > + } > + > + if (RD->hasDefinition()) { > + // Assign inheritance models to all of the base classes, because now > we can > + // form pointers to members of base classes without calling > + // RequireCompleteType on the pointer to member of the base class > type. > + for (const CXXBaseSpecifier &BS : RD->bases()) > + assignInheritanceModel(S, BS.getType()->getAsCXXRecordDecl()); > + } > +} > + > /// \brief The implementation of RequireCompleteType > bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T, > TypeDiagnoser &Diagnoser) { > @@ -5185,36 +5224,7 @@ bool Sema::RequireCompleteTypeImpl(Sourc > if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>()) { > if (!MPTy->getClass()->isDependentType()) { > RequireCompleteType(Loc, QualType(MPTy->getClass(), 0), 0); > - > - CXXRecordDecl *RD = MPTy->getMostRecentCXXRecordDecl(); > - if (!RD->hasAttr<MSInheritanceAttr>()) { > - MSInheritanceAttr::Spelling InheritanceModel; > - > - switch (MSPointerToMemberRepresentationMethod) { > - case LangOptions::PPTMK_BestCase: > - InheritanceModel = RD->calculateInheritanceModel(); > - break; > - case LangOptions::PPTMK_FullGeneralitySingleInheritance: > - InheritanceModel = > MSInheritanceAttr::Keyword_single_inheritance; > - break; > - case LangOptions::PPTMK_FullGeneralityMultipleInheritance: > - InheritanceModel = > - MSInheritanceAttr::Keyword_multiple_inheritance; > - break; > - case LangOptions::PPTMK_FullGeneralityVirtualInheritance: > - InheritanceModel = > - MSInheritanceAttr::Keyword_unspecified_inheritance; > - break; > - } > - > - RD->addAttr(MSInheritanceAttr::CreateImplicit( > - getASTContext(), InheritanceModel, > - /*BestCase=*/MSPointerToMemberRepresentationMethod == > - LangOptions::PPTMK_BestCase, > - ImplicitMSInheritanceAttrLoc.isValid() > - ? ImplicitMSInheritanceAttrLoc > - : RD->getSourceRange())); > - } > + assignInheritanceModel(*this, > MPTy->getMostRecentCXXRecordDecl()); > } > } > } > > Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp?rev=210813&r1=210812&r2=210813&view=diff > > ============================================================================== > --- cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp (original) > +++ cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp Thu Jun 12 > 14:49:17 2014 > @@ -1,5 +1,5 @@ > -// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 | > FileCheck %s > -// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 | > FileCheck %s -check-prefix=X64 > +// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 > -fms-extensions | FileCheck %s > +// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 > -fms-extensions | FileCheck %s -check-prefix=X64 > // RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 > -DINCOMPLETE_VIRTUAL -fms-extensions -verify > // RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 > -DINCOMPLETE_VIRTUAL -DMEMFUN -fms-extensions -verify > // FIXME: Test x86_64 member pointers when codegen no longer asserts on > records > @@ -607,6 +607,29 @@ void (C::*getmp())() { > > } > > +namespace pr2007 { > +struct A { > + void f(); > + void f(int); > +}; > +struct B : public A {}; > +void test() { void (B::*a)() = &B::f; } > +// CHECK-LABEL: define void @"\01?test@pr2007@@YAXXZ" > +// CHECK: store i8* bitcast (void (%"struct.pr2007::A"*)* @"\01?f@A > @pr2007@@QAEXXZ" to i8*) > +} > + > +namespace pr2007_kw { > +struct A { > + void f(); > + void f(int); > +}; > +struct __single_inheritance B; > +struct B : public A {}; > +void test() { void (B::*a)() = &B::f; } > +// CHECK-LABEL: define void @"\01?test@pr2007_kw@@YAXXZ" > +// CHECK: store i8* bitcast (void (%"struct.pr2007_kw::A"*)* @"\01?f@A > @pr2007_kw@@QAEXXZ" to i8*) > +} > + > #else > struct __virtual_inheritance A; > #ifdef MEMFUN > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
