Index: include/clang/AST/DeclCXX.h
==================================================================
--- include/clang/AST/DeclCXX.h
+++ include/clang/AST/DeclCXX.h
@@ -1554,13 +1554,16 @@
 
   bool isVirtual() const {
     CXXMethodDecl *CD =
       cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
 
-    // Methods declared in interfaces are automatically (pure) virtual
+    // Methods declared in interfaces are automatically (pure) virtual.
     if (CD->isVirtualAsWritten() ||
-        CD->getParent()->getTagKind() == TTK_Interface)
+          (CD->getParent()->isInterface()
+             && !isa<CXXConstructorDecl>(CD)
+             && !isa<CXXDestructorDecl>(CD)
+             && CD->getOverloadedOperator() == OO_None))
       return true;
 
     return (CD->begin_overridden_methods() != CD->end_overridden_methods());
   }
 

Index: lib/Sema/SemaDecl.cpp
==================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -5191,16 +5191,21 @@
       //   A function can be defined in a friend declaration of a
       //   class . . . . Such a function is implicitly inline.
       NewFD->setImplicitlyInline();
     }
 
-    // if this is a method defined in an __interface, set pure
-    // (isVirtual will already return true)
-    if (CXXRecordDecl *Parent = dyn_cast<CXXRecordDecl>(
-        NewFD->getDeclContext())) {
-      if (Parent->getTagKind() == TTK_Interface)
+    // If this is a method defined in an __interface, and is not a constructor
+    // or an overloaded operator, then set the pure flag (isVirtual will already
+    // return true).
+    if (const CXXRecordDecl *Parent =
+          dyn_cast<CXXRecordDecl>(NewFD->getDeclContext())) {
+      if (Parent->isInterface()
+            && !isa<CXXConstructorDecl>(NewFD)
+            && !isa<CXXDestructorDecl>(NewFD)
+            && NewFD->getOverloadedOperator() == OO_None) {
         NewFD->setPure(true);
+      }
     }
 
     SetNestedNameSpecifier(NewFD, D);
     isExplicitSpecialization = false;
     isFunctionTemplateSpecialization = false;

ADDED    test/CodeGenCXX/microsoft-interface.cpp
Index: test/CodeGenCXX/microsoft-interface.cpp
==================================================================
--- test/CodeGenCXX/microsoft-interface.cpp
+++ test/CodeGenCXX/microsoft-interface.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -std=c++11 -fms-extensions -Wno-microsoft -triple=i386-pc-win32 -emit-llvm %s -o - | FileCheck %s
+
+__interface I {
+  int test() {
+    return 1;
+  }
+};
+
+struct S : I {
+  virtual int test() override {
+    return I::test();
+  }
+};
+
+int fn() {
+  S s;
+  return s.test();
+}
+
+// CHECK: @_ZTV1S = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1S to i8*), i8* bitcast (i32 (%struct.S*)* @_ZN1S4testEv to i8*)]
+
+// CHECK: define i32 @_Z2fnv()
+// CHECK:   call void @_ZN1SC1Ev(%struct.S* %s)
+// CHECK:   %call = call i32 @_ZN1S4testEv(%struct.S* %s)
+
+// CHECK: define linkonce_odr void @_ZN1SC1Ev(%struct.S* %this)
+// CHECK:   call void @_ZN1SC2Ev(%struct.S* %this1)
+
+// CHECK: define linkonce_odr i32 @_ZN1S4testEv(%struct.S* %this)
+// CHECK:   %call = call i32 @_ZN1I4testEv(%__interface.I* %0)
+
+// CHECK: define linkonce_odr i32 @_ZN1I4testEv(%__interface.I* %this)
+// CHECK:   ret i32 1
+
+// CHECK: define linkonce_odr void @_ZN1SC2Ev(%struct.S* %this)
+// CHECK:   call void @_ZN1IC2Ev(%__interface.I* %0)
+// CHECK:   store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1S, i64 0, i64 2), i8*** %1
+
+// CHECK: define linkonce_odr void @_ZN1IC2Ev(%__interface.I* %this)
+// CHECK:   store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1I, i64 0, i64 2), i8*** %0
+
+// CHECK-NOT: define linkonce_odr %__interface.I* @_ZN1IaSERKS_(%__interface.I* %this, %__interface.I*)
+// CHECK-NOT: define linkonce_odr %__interface.I* @_ZN1IaSEOS_(%__interface.I* %this, %__interface.I*)
