Fix typo correction usage of SemaAccess.cpp.

When we check access for lookup results, make sure we propagate the
result's access to the access control APIs; this can be different from
the natural access of the declaration depending on the path used by the lookup.

PR17394.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@191726 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 116b427..3782455 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -4896,7 +4896,7 @@
   AccessResult CheckFriendAccess(NamedDecl *D);
   AccessResult CheckMemberAccess(SourceLocation UseLoc,
                                  CXXRecordDecl *NamingClass,
-                                 NamedDecl *D);
+                                 DeclAccessPair Found);
   AccessResult CheckMemberOperatorAccess(SourceLocation Loc,
                                          Expr *ObjectExpr,
                                          Expr *ArgExpr,
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp
index 6dbfad4..974f3b4 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -1390,8 +1390,6 @@
   CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths);
   if (!Path)
     return AR_dependent;
-  if (Path->Access == AS_none)  // This can happen during typo correction.
-    return AR_inaccessible;
 
   assert(Path->Access <= UnprivilegedAccess &&
          "access along best path worse than direct?");
@@ -1716,14 +1714,14 @@
 /// \brief Checks access to a member.
 Sema::AccessResult Sema::CheckMemberAccess(SourceLocation UseLoc,
                                            CXXRecordDecl *NamingClass,
-                                           NamedDecl *D) {
+                                           DeclAccessPair Found) {
   if (!getLangOpts().AccessControl ||
       !NamingClass ||
-      D->getAccess() == AS_public)
+      Found.getAccess() == AS_public)
     return AR_accessible;
 
   AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
-                      DeclAccessPair::make(D, D->getAccess()), QualType());
+                      Found, QualType());
 
   return CheckAccess(*this, UseLoc, Entity);
 }
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index c2e23c7..2a096cf 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -4409,7 +4409,7 @@
                  TRD != TRDEnd; ++TRD) {
               if (CheckMemberAccess(TC.getCorrectionRange().getBegin(),
                                     NSType ? NSType->getAsCXXRecordDecl() : 0,
-                                    *TRD) == AR_accessible)
+                                    TRD.getPair()) == AR_accessible)
                 TC.addCorrectionDecl(*TRD);
             }
             if (TC.isResolved())
diff --git a/test/SemaCXX/typo-correction-pt2.cpp b/test/SemaCXX/typo-correction-pt2.cpp
index 1ccd103..9c7fb14 100644
--- a/test/SemaCXX/typo-correction-pt2.cpp
+++ b/test/SemaCXX/typo-correction-pt2.cpp
@@ -135,3 +135,12 @@
     req.set_check(false);  // expected-error-re {{use of undeclared identifier 'req'$}}
 }
 }
+
+namespace PR17394 {
+  class A {
+  protected:
+    long zzzzzzzzzz;
+  };
+  class B : private A {};
+  B zzzzzzzzzy<>; // expected-error {{expected ';' after top level declarator}}{}
+}