diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index bfb98413a8a6f52f04e5730a809fef9b31e678b6..d55ac5ee8335c6dd64c58c603470fa83a3ec3ef1 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -677,6 +677,10 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { if (T.hasQualifiers()) T = T.getUnqualifiedType(); + if (T->isMemberPointerType() && + Context.getTargetInfo().getCXXABI().isMicrosoft()) + RequireCompleteType(E->getExprLoc(), T, 0); + UpdateMarkingForLValueToRValue(E); // Loading a __weak object implicitly retains the value, so we need a cleanup to diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index a48e634c3cda1edaeea4c966d39c4e90e40788bf..e52aca14869ba3183c1d85fb4f1b76f4947bd86d 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -4507,6 +4507,8 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS, << OpSpelling << RHSType << RHS.get()->getSourceRange(); return QualType(); } + //if (Context.getTargetInfo().getCXXABI().isMicrosoft()) + // RequireCompleteType(Loc, QualType(MemPtr, 0), 0); QualType Class(MemPtr->getClass(), 0); diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 6b7a49dc335c484680b077a780acc8b2e2a45b0d..63e69d3281b1936143aee684e9ab16bdbefac897 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -6253,9 +6253,13 @@ bool Sema::RequireCompleteExprType(Expr *E, TypeDiagnoser &Diagnoser){ QualType T = E->getType(); // Fast path the case where the type is already complete. - if (!T->isIncompleteType()) + if (!T->isIncompleteType()) { + if (T->isMemberPointerType() && + Context.getTargetInfo().getCXXABI().isMicrosoft()) + RequireCompleteType(E->getExprLoc(), T, 0); // FIXME: The definition might not be visible. return false; + } // Incomplete array types may be completed by the initializer attached to // their definitions. For static data members of class templates and for diff --git a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp index 25d7c7702da027fa9f17b0ec1eb7bad76f9085e4..5d120700c84e50ee76ebec2b6f85902c57836a96 100644 --- a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp +++ b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp @@ -752,3 +752,19 @@ void f(int S::*&p) {} // CHECK-LABEL: define void @"\01?f@PR24703@@YAXAAPQS@1@H@Z"( } +namespace ReferenceToMPTWithIncompleteClass { +struct S; +struct J; +struct K; +extern K *k; + +// CHECK-LABEL: @"\01?f@ReferenceToMPTWithIncompleteClass@@YAIAAPQS@1@H@Z"( +// CHECK: ret i32 12 +unsigned f(int S::*&p) { return sizeof p; } + +// CHECK-LABEL: @"\01?g@ReferenceToMPTWithIncompleteClass@@YA_NAAPQJ@1@H0@Z"( +bool g(int J::*&p, int J::*&q) { return p == q; } + +// CHECK-LABEL: @"\01?h@ReferenceToMPTWithIncompleteClass@@YAHAAPQK@1@H@Z"( +int h(int K::*&p) { return k->*p; } +}