diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index f1d0395..fc79391 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -166,6 +166,48 @@ static bool canDevirtualizeMemberFunctionCalls(ASTContext &Context,
   return false;
 }
 
+static bool recursivellyOverrides(const CXXMethodDecl *DerivedMD,
+                                  const CXXMethodDecl *BaseMD) {
+  for (CXXMethodDecl::method_iterator I = DerivedMD->begin_overridden_methods(),
+         E = DerivedMD->end_overridden_methods(); I != E; ++I) {
+    const CXXMethodDecl *MD = *I;
+    if (MD == BaseMD)
+      return true;
+    if (recursivellyOverrides(MD, BaseMD))
+      return true;
+  }
+  return false;
+}
+
+static const CXXMethodDecl *
+getCorrespondingMethodInClass(const CXXMethodDecl *MD,
+                              const CXXRecordDecl *RD) {
+  // FIXME: Is there an easier way of iterating over all methods (inherited
+  // or not)?
+  // Should this be using some walker?
+
+  if (MD->getParent() == RD)
+    return MD;
+
+  for (CXXRecordDecl::method_iterator I = RD->method_begin(),
+         E = RD->method_end(); I != E; ++I) {
+    CXXMethodDecl *DMD = *I;
+    if (recursivellyOverrides(DMD, MD))
+      return DMD;
+  }
+
+  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+         E = RD->bases_end(); I != E; ++I) {
+    const CXXRecordDecl *Base =
+      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+    const CXXMethodDecl *T = getCorrespondingMethodInClass(MD, Base);
+    if (T)
+      return T;
+  }
+
+  return NULL;
+}
+
 // Note: This function also emit constructor calls to support a MSVC
 // extensions allowing explicit constructor function call.
 RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
@@ -273,8 +315,14 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
         MD->isVirtual() &&
         ME->hasQualifier())
       Callee = BuildAppleKextVirtualCall(MD, ME->getQualifier(), Ty);
-    else 
-      Callee = CGM.GetAddrOfFunction(MD, Ty);
+    else {
+      const Expr *Base = ME->getBase();
+      const CXXRecordDecl *MostDerivedClassDecl = getMostDerivedClassDecl(Base);
+      const CXXMethodDecl *DerivedMethod =
+        getCorrespondingMethodInClass(MD, MostDerivedClassDecl);
+      assert(DerivedMethod);
+      Callee = CGM.GetAddrOfFunction(DerivedMethod, Ty);
+    }
   }
 
   return EmitCXXMemberCall(MD, Callee, ReturnValue, This, /*VTT=*/0,
diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
index 3de75ed..8180cd9 100644
--- a/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
+++ b/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
@@ -49,3 +49,38 @@ namespace Test3 {
     return static_cast<B*>(v)->f();
   }
 }
+
+namespace Test4 {
+  struct A {
+    virtual void f();
+  };
+
+  struct B final : A {
+    virtual void f();
+  };
+
+  // CHECK: define void @_ZN5Test41fEPNS_1BE
+  void f(B* d) {
+    // CHECK: call void @_ZN5Test41B1fEv
+    static_cast<A*>(d)->f();
+  }
+}
+
+namespace Test5 {
+  struct A {
+    virtual void f();
+  };
+
+  struct B : A {
+    virtual void f();
+  };
+
+  struct C final : B {
+  };
+
+  // CHECK: define void @_ZN5Test51fEPNS_1CE
+  void f(C* d) {
+    // CHECK: call void @_ZN5Test51B1fEv
+    static_cast<A*>(d)->f();
+  }
+}
