Index: lib/Sema/SemaDeclCXX.cpp =================================================================== --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -4377,11 +4377,24 @@ // specialization bases. for (Decl *Member : Class->decls()) { - if (!isa(Member) && !isa(Member)) + VarDecl *VD = dyn_cast(Member); + CXXMethodDecl *MD = dyn_cast(Member); + + // Only methods and static fields inherit the attributes. + if (!VD && !MD) continue; - if (isa(Member) && cast(Member)->isDeleted()) + + // Don't process deleted methods. + if (MD && MD->isDeleted()) continue; + if (MD && MD->isMoveAssignmentOperator() && !ClassExported && + MD->isInlined()) { + // Current MSVC versions don't export the move assignment operators, so + // don't attempt to import them if we have a definition. + continue; + } + if (InheritableAttr *MemberAttr = getDLLAttr(Member)) { if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() && !MemberAttr->isInherited()) { Index: test/CodeGenCXX/dllimport.cpp =================================================================== --- test/CodeGenCXX/dllimport.cpp +++ test/CodeGenCXX/dllimport.cpp @@ -27,6 +27,8 @@ #define USE(func) void UNIQ(use)() { func(); } #define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; } #define USECLASS(class) void UNIQ(USE)() { class x; } +#define USECOPYASSIGN(class) class& (class::*UNIQ(use)())(class&) { return &class::operator=; } +#define USEMOVEASSIGN(class) class& (class::*UNIQ(use)())(class&&) { return &class::operator=; } //===----------------------------------------------------------------------===// // Globals @@ -518,9 +520,18 @@ static int b; // MO1-DAG: @"\01?b@T@@2HA" = external dllimport global i32 + + T& operator=(T&) = default; + // MO1-DAG: define available_externally dllimport x86_thiscallcc nonnull %struct.T* @"\01??4T@@QAEAAU0@AAU0@@Z" + + T& operator=(T&&) = default; + // Note: Don't mark inline move operators dllimport because current MSVC versions don't export them. + // MO1-DAG: define linkonce_odr x86_thiscallcc nonnull %struct.T* @"\01??4T@@QAEAAU0@$$QAU0@@Z" }; USEMEMFUNC(T, a) USEVAR(T::b) +USECOPYASSIGN(T) +USEMOVEASSIGN(T) template struct __declspec(dllimport) U { void foo() {} }; // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01?foo@?$U@H@@QAEXXZ"