Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 151796)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -834,6 +834,10 @@
   "field of type %0 has %select{private|protected}2 "
   "%select{default |copy |move |*ERROR* |*ERROR* |*ERROR* |}1constructor">,
   AccessControl;
+def err_in_this_context : Error<
+  // This is used when diagnosing friend declarations with 
+  // access control errors
+  "within this context">, AccessControl;
 
 def err_access_dtor : Error<
   "calling a %select{private|protected}1 destructor of class %0">, 
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp	(revision 151796)
+++ lib/Sema/SemaDeclCXX.cpp	(working copy)
@@ -10166,7 +10166,25 @@
         DB << FixItHint::CreateRemoval(SS.getRange());
       SS.clear();
     }
-
+    
+    for (LookupResult::iterator iter = Previous.begin(), end = Previous.end();
+          iter != end; ++iter) {
+      // C++ [class.friend]p9:
+      //  A name nominated by a friend declaration shall be accessible in the 
+      //  scope of the class containing the friend declaration.
+      AccessSpecifier Access = (*iter)->getAccess();
+      RecordDecl *Owner = dyn_cast<RecordDecl>(DC);
+      if (Owner && Access != AS_public) {
+        Diag((*iter)->getLocation(), diag::err_access) 
+              << ((Access == AS_private) ? 0 : 1)
+              << (*iter)->getName()
+              << 0 /*ignored*/
+              << Owner->getName();
+        Diag(Loc, diag::err_in_this_context);
+        return 0;
+      }
+    }
+    
   //   - There's a scope specifier that does not match any template
   //     parameter lists, in which case we use some arbitrary context,
   //     create a method or method template, and wait for instantiation.
Index: test/SemaCXX/friend.cpp
===================================================================
--- test/SemaCXX/friend.cpp	(revision 151796)
+++ test/SemaCXX/friend.cpp	(working copy)
@@ -130,3 +130,17 @@
     v.f();
   }
 }
+
+namespace PR12126 {
+  class A {
+  private:
+    void f() {}  // expected-error{{f is a private member of A}}
+  protected:
+    void g() {}  // expected-error{{g is a protected member of A}}
+  };
+
+  class B {
+    friend void A::f();  // expected-error{{within this context}}
+    friend void A::g();  // expected-error{{within this context}}
+  };
+}
