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