From 91d3f338e446e654392184e68f940c77b5c98f39 Mon Sep 17 00:00:00 2001
From: Eli Friedman <eli.friedman@gmail.com>
Date: Tue, 1 Oct 2013 02:44:48 +0000
Subject: [PATCH] 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
---
 include/clang/Sema/Sema.h            | 2 +-
 lib/Sema/SemaAccess.cpp              | 8 +++-----
 lib/Sema/SemaLookup.cpp              | 2 +-
 test/SemaCXX/typo-correction-pt2.cpp | 9 +++++++++
 4 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 116b427266..378245585a 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -4896,7 +4896,7 @@ public:
   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 6dbfad4e18..974f3b42db 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -1390,8 +1390,6 @@ static AccessResult IsAccessible(Sema &S,
   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 @@ Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
 /// \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 c2e23c7ede..2a096cfd97 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -4409,7 +4409,7 @@ retry_lookup:
                  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 1ccd103ecf..9c7fb14ccf 100644
--- a/test/SemaCXX/typo-correction-pt2.cpp
+++ b/test/SemaCXX/typo-correction-pt2.cpp
@@ -135,3 +135,12 @@ void test() {
     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}}{}
+}
-- 
2.40.0