<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Jun 12, 2014 at 12:49 PM, Reid Kleckner <span dir="ltr"><<a href="mailto:reid@kleckner.net" target="_blank">reid@kleckner.net</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: rnk<br>
Date: Thu Jun 12 14:49:17 2014<br>
New Revision: 210813<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=210813&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=210813&view=rev</a><br>
Log:<br>
MS ABI: Fix forming pointers to members of a base class<br>
<br>
Previously we would calculate the inheritance model of a class when<br>
requiring a pointer to member type of that class to be complete.  The<br>
inheritance model is used to figure out how many fields are used by the<br>
member pointer.<br>
<br>
However, once we require a pointer to member of a derived class type to<br>
be complete, we can form pointers to members of bases without<br>
calculating the inheritance model for those bases.  This was causing<br>
crashes on this simple test case:<br>
<br>
  struct A {<br>
    void f();<br>
    void f(int);<br>
  };<br>
  struct B : public A {};<br>
  void g() { void (B::*a)() = &B::f; }<br>
<br>
Now we calculate the inheritance models of all base classes when<br>
completing a member pointer type.<br>
<br>
Fixes PR2007.<br></blockquote><div><br></div><div>PR20007 (one more 0), right? (Also in the test)<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<br>
Modified:<br>
    cfe/trunk/lib/Sema/SemaType.cpp<br>
    cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaType.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=210813&r1=210812&r2=210813&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=210813&r1=210812&r2=210813&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaType.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Jun 12 14:49:17 2014<br>
@@ -5147,6 +5147,45 @@ static bool hasVisibleDefinition(Sema &S<br>
   return LookupResult::isVisible(S, D);<br>
 }<br>
<br>
+/// Locks in the inheritance model for the given class and all of its bases.<br>
+static void assignInheritanceModel(Sema &S, CXXRecordDecl *RD) {<br>
+  RD = RD->getMostRecentDecl();<br>
+  if (!RD->hasAttr<MSInheritanceAttr>()) {<br>
+    MSInheritanceAttr::Spelling IM;<br>
+<br>
+    switch (S.MSPointerToMemberRepresentationMethod) {<br>
+    case LangOptions::PPTMK_BestCase:<br>
+      IM = RD->calculateInheritanceModel();<br>
+      break;<br>
+    case LangOptions::PPTMK_FullGeneralitySingleInheritance:<br>
+      IM = MSInheritanceAttr::Keyword_single_inheritance;<br>
+      break;<br>
+    case LangOptions::PPTMK_FullGeneralityMultipleInheritance:<br>
+      IM = MSInheritanceAttr::Keyword_multiple_inheritance;<br>
+      break;<br>
+    case LangOptions::PPTMK_FullGeneralityVirtualInheritance:<br>
+      IM = MSInheritanceAttr::Keyword_unspecified_inheritance;<br>
+      break;<br>
+    }<br>
+<br>
+    RD->addAttr(MSInheritanceAttr::CreateImplicit(<br>
+        S.getASTContext(), IM,<br>
+        /*BestCase=*/S.MSPointerToMemberRepresentationMethod ==<br>
+            LangOptions::PPTMK_BestCase,<br>
+        S.ImplicitMSInheritanceAttrLoc.isValid()<br>
+            ? S.ImplicitMSInheritanceAttrLoc<br>
+            : RD->getSourceRange()));<br>
+  }<br>
+<br>
+  if (RD->hasDefinition()) {<br>
+    // Assign inheritance models to all of the base classes, because now we can<br>
+    // form pointers to members of base classes without calling<br>
+    // RequireCompleteType on the pointer to member of the base class type.<br>
+    for (const CXXBaseSpecifier &BS : RD->bases())<br>
+      assignInheritanceModel(S, BS.getType()->getAsCXXRecordDecl());<br>
+  }<br>
+}<br>
+<br>
 /// \brief The implementation of RequireCompleteType<br>
 bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T,<br>
                                    TypeDiagnoser &Diagnoser) {<br>
@@ -5185,36 +5224,7 @@ bool Sema::RequireCompleteTypeImpl(Sourc<br>
       if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>()) {<br>
         if (!MPTy->getClass()->isDependentType()) {<br>
           RequireCompleteType(Loc, QualType(MPTy->getClass(), 0), 0);<br>
-<br>
-          CXXRecordDecl *RD = MPTy->getMostRecentCXXRecordDecl();<br>
-          if (!RD->hasAttr<MSInheritanceAttr>()) {<br>
-            MSInheritanceAttr::Spelling InheritanceModel;<br>
-<br>
-            switch (MSPointerToMemberRepresentationMethod) {<br>
-            case LangOptions::PPTMK_BestCase:<br>
-              InheritanceModel = RD->calculateInheritanceModel();<br>
-              break;<br>
-            case LangOptions::PPTMK_FullGeneralitySingleInheritance:<br>
-              InheritanceModel = MSInheritanceAttr::Keyword_single_inheritance;<br>
-              break;<br>
-            case LangOptions::PPTMK_FullGeneralityMultipleInheritance:<br>
-              InheritanceModel =<br>
-                  MSInheritanceAttr::Keyword_multiple_inheritance;<br>
-              break;<br>
-            case LangOptions::PPTMK_FullGeneralityVirtualInheritance:<br>
-              InheritanceModel =<br>
-                  MSInheritanceAttr::Keyword_unspecified_inheritance;<br>
-              break;<br>
-            }<br>
-<br>
-            RD->addAttr(MSInheritanceAttr::CreateImplicit(<br>
-                getASTContext(), InheritanceModel,<br>
-                /*BestCase=*/MSPointerToMemberRepresentationMethod ==<br>
-                    LangOptions::PPTMK_BestCase,<br>
-                ImplicitMSInheritanceAttrLoc.isValid()<br>
-                    ? ImplicitMSInheritanceAttrLoc<br>
-                    : RD->getSourceRange()));<br>
-          }<br>
+          assignInheritanceModel(*this, MPTy->getMostRecentCXXRecordDecl());<br>
         }<br>
       }<br>
     }<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp?rev=210813&r1=210812&r2=210813&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp?rev=210813&r1=210812&r2=210813&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-member-pointers.cpp Thu Jun 12 14:49:17 2014<br>
@@ -1,5 +1,5 @@<br>
-// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s<br>
-// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s -check-prefix=X64<br>
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-extensions | FileCheck %s<br>
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-extensions | FileCheck %s -check-prefix=X64<br>
 // RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -fms-extensions -verify<br>
 // RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -DMEMFUN -fms-extensions -verify<br>
 // FIXME: Test x86_64 member pointers when codegen no longer asserts on records<br>
@@ -607,6 +607,29 @@ void (C::*getmp())() {<br>
<br>
 }<br>
<br>
+namespace pr2007 {<br>
+struct A {<br>
+  void f();<br>
+  void f(int);<br>
+};<br>
+struct B : public A {};<br>
+void test() { void (B::*a)() = &B::f; }<br>
+// CHECK-LABEL: define void @"\01?test@pr2007@@YAXXZ"<br>
+// CHECK: store i8* bitcast (void (%"struct.pr2007::A"*)* @"\01?f@A@pr2007@@QAEXXZ" to i8*)<br>
+}<br>
+<br>
+namespace pr2007_kw {<br>
+struct A {<br>
+  void f();<br>
+  void f(int);<br>
+};<br>
+struct __single_inheritance B;<br>
+struct B : public A {};<br>
+void test() { void (B::*a)() = &B::f; }<br>
+// CHECK-LABEL: define void @"\01?test@pr2007_kw@@YAXXZ"<br>
+// CHECK: store i8* bitcast (void (%"struct.pr2007_kw::A"*)* @"\01?f@A@pr2007_kw@@QAEXXZ" to i8*)<br>
+}<br>
+<br>
 #else<br>
 struct __virtual_inheritance A;<br>
 #ifdef MEMFUN<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>