r210813 - MS ABI: Fix forming pointers to members of a base class
Nico Weber
thakis at chromium.org
Thu Jun 12 14:18:18 PDT 2014
On Thu, Jun 12, 2014 at 12:49 PM, Reid Kleckner <reid at kleckner.net> 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 at pr2007@@YAXXZ"
> +// CHECK: store i8* bitcast (void (%"struct.pr2007::A"*)* @"\01?f at 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 at pr2007_kw@@YAXXZ"
> +// CHECK: store i8* bitcast (void (%"struct.pr2007_kw::A"*)* @"\01?f at A
> @pr2007_kw@@QAEXXZ" to i8*)
> +}
> +
> #else
> struct __virtual_inheritance A;
> #ifdef MEMFUN
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140612/378bc5b7/attachment.html>
More information about the cfe-commits
mailing list