diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 06004bd00c..136de7c221 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1733,12 +1733,12 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class, // when passing pointers between TUs that disagree about the size. if (Context.getTargetInfo().getCXXABI().isMicrosoft()) { CXXRecordDecl *RD = Class->getAsCXXRecordDecl(); - if (!RD || !RD->hasAttr()) { + if (RD && !RD->hasAttr()) { // Lock in the inheritance model on the first use of a member pointer. // Otherwise we may disagree about the size at different points in the TU. // FIXME: MSVC picks a model on the first use that needs to know the size, // rather than on the first mention of the type, e.g. typedefs. - if (RequireCompleteType(Loc, Class, 0) && RD && !RD->isBeingDefined()) { + if (RequireCompleteType(Loc, Class, 0) && !RD->isBeingDefined()) { // We know it doesn't have an attribute and it's incomplete, so use the // unspecified inheritance model. If we're in the record body, we can // figure out the inheritance model. diff --git a/test/SemaCXX/member-pointer-ms.cpp b/test/SemaCXX/member-pointer-ms.cpp index f4919d221d..7dca121905 100644 --- a/test/SemaCXX/member-pointer-ms.cpp +++ b/test/SemaCXX/member-pointer-ms.cpp @@ -132,3 +132,36 @@ struct MemPtrInBody { }; static_assert(sizeof(MemPtrInBody::MemPtr) == kSingleDataSize, ""); + +// Passing a member pointer through a template should get the right size. +template +struct SingleTemplate; +template +struct SingleTemplate { + static_assert(sizeof(int T::*) == kSingleDataSize, ""); + static_assert(sizeof(void (T::*)()) == kSingleFunctionSize, ""); +}; + +template +struct UnspecTemplate; +template +struct UnspecTemplate { + static_assert(sizeof(int T::*) == kUnspecifiedDataSize, ""); + static_assert(sizeof(void (T::*)()) == kUnspecifiedFunctionSize, ""); +}; + +struct NewUnspecified; +SingleTemplate tmpl_single; +UnspecTemplate tmpl_unspec; + +struct NewUnspecified { }; + +static_assert(sizeof(void (NewUnspecified::*)()) == kUnspecifiedFunctionSize, ""); + +template +struct MemPtrInTemplate { + // We can't require that the template arg be complete until we're + // instantiated. + int T::*data_ptr; + void (T::*func_ptr)(); +};