Fix PR4878 for real.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81507 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index a4a6123..4df55e6 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1002,7 +1002,16 @@
           MarkDeclarationReferenced(Loc, D);
           if (PerformObjectMemberConversion(This, D))
             return ExprError();
-          if (DiagnoseUseOfDecl(D, Loc))
+          
+          bool ShouldCheckUse = true;
+          if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+            // Don't diagnose the use of a virtual member function unless it's
+            // explicitly qualified.
+            if (MD->isVirtual() && (!SS || !SS->isSet()))
+              ShouldCheckUse = false;
+          }
+          
+          if (ShouldCheckUse && DiagnoseUseOfDecl(D, Loc))
             return ExprError();
           return Owned(BuildMemberExpr(Context, This, true, SS, D,
                                        Loc, MemberType));
diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp
index 10b4a55..c1bdfcc 100644
--- a/test/SemaCXX/attr-deprecated.cpp
+++ b/test/SemaCXX/attr-deprecated.cpp
@@ -27,12 +27,25 @@
 
 struct B {
   virtual void f() __attribute__((deprecated));
+  void g();
 };
 
+void B::g() {
+  f();
+  B::f(); // expected-warning{{'f' is deprecated}}
+}
+
 struct C : B {
   virtual void f();
+  void g();
 };
 
+void C::g() {
+  f();
+  C::f();
+  B::f(); // expected-warning{{'f' is deprecated}}
+}
+
 void f(B* b, C *c) {
   b->f();
   b->B::f(); // expected-warning{{'f' is deprecated}}