Enforce access control for conversion operators used in contextual
conversions (rather than just call-arguments).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140244 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h
index 9d26202..214f8c0 100644
--- a/include/clang/Sema/Overload.h
+++ b/include/clang/Sema/Overload.h
@@ -256,7 +256,7 @@
     /// \brief The declaration that we found via name lookup, which might be
     /// the same as \c ConversionFunction or it might be a using declaration
     /// that refers to \c ConversionFunction.
-    NamedDecl *FoundConversionFunction;
+    DeclAccessPair FoundConversionFunction;
     
     void DebugPrint() const;
   };
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp
index e501a39..a2d078b 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -1551,8 +1551,7 @@
       Found.getAccess() == AS_public)
     return AR_accessible;
 
-  const RecordType *RT = ObjectExpr->getType()->getAs<RecordType>();
-  assert(RT && "found member operator but object expr not of record type");
+  const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>();
   CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
 
   AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 98f96bc..1741bdb 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -2065,7 +2065,7 @@
                                        QualType Ty,
                                        CastKind Kind,
                                        CXXMethodDecl *Method,
-                                       NamedDecl *FoundDecl,
+                                       DeclAccessPair FoundDecl,
                                        Expr *From) {
   switch (Kind) {
   default: assert(0 && "Unhandled cast kind!");
@@ -2096,6 +2096,8 @@
     if (Result.isInvalid())
       return ExprError();
 
+    S.CheckMemberOperatorAccess(CastLoc, From, /*arg*/ 0, FoundDecl);
+
     return S.MaybeBindToTemporary(Result.get());
   }
   }
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index c084f76..806fd39 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -2509,7 +2509,7 @@
         User.EllipsisConversion = false;
       }
       User.ConversionFunction = Constructor;
-      User.FoundConversionFunction = Best->FoundDecl.getDecl();
+      User.FoundConversionFunction = Best->FoundDecl;
       User.After.setAsIdentityConversion();
       User.After.setFromType(ThisType->getAs<PointerType>()->getPointeeType());
       User.After.setAllToTypes(ToType);
@@ -2526,7 +2526,7 @@
       //   implicit object parameter of the conversion function.
       User.Before = Best->Conversions[0].Standard;
       User.ConversionFunction = Conversion;
-      User.FoundConversionFunction = Best->FoundDecl.getDecl();
+      User.FoundConversionFunction = Best->FoundDecl;
       User.EllipsisConversion = false;
 
       // C++ [over.ics.user]p2:
@@ -3367,7 +3367,7 @@
     ICS.UserDefined.Before = Best->Conversions[0].Standard;
     ICS.UserDefined.After = Best->FinalConversion;
     ICS.UserDefined.ConversionFunction = Best->Function;
-    ICS.UserDefined.FoundConversionFunction = Best->FoundDecl.getDecl();
+    ICS.UserDefined.FoundConversionFunction = Best->FoundDecl;
     ICS.UserDefined.EllipsisConversion = false;
     assert(ICS.UserDefined.After.ReferenceBinding &&
            ICS.UserDefined.After.DirectBinding &&
@@ -4754,8 +4754,7 @@
   Candidate.Conversions[0].UserDefined.Before = ObjectInit.Standard;
   Candidate.Conversions[0].UserDefined.EllipsisConversion = false;
   Candidate.Conversions[0].UserDefined.ConversionFunction = Conversion;
-  Candidate.Conversions[0].UserDefined.FoundConversionFunction
-    = FoundDecl.getDecl();
+  Candidate.Conversions[0].UserDefined.FoundConversionFunction = FoundDecl;
   Candidate.Conversions[0].UserDefined.After
     = Candidate.Conversions[0].UserDefined.Before;
   Candidate.Conversions[0].UserDefined.After.setAsIdentityConversion();
diff --git a/test/CXX/class.access/p6.cpp b/test/CXX/class.access/p6.cpp
index fe3304a..932b4f4 100644
--- a/test/CXX/class.access/p6.cpp
+++ b/test/CXX/class.access/p6.cpp
@@ -168,3 +168,25 @@
     void foo(int arg[__builtin_offsetof(B, ins)]);
   }
 }
+
+// rdar://problem/10155256
+namespace test8 {
+  class A {
+    typedef void* (A::*UnspecifiedBoolType)() const;
+    operator UnspecifiedBoolType() const; // expected-note {{implicitly declared private here}}
+  };
+
+  void test(A &a) {
+    if (a) return; // expected-error {{'operator void *(class test8::A::*)(void) const' is a private member of 'test8::A'}}
+  }
+}
+
+namespace test9 {
+  class A {
+    operator char*() const; // expected-note {{implicitly declared private here}}
+  };
+
+  void test(A &a) {
+    delete a; // expected-error {{'operator char *' is a private member of 'test9::A'}}
+  }
+}
diff --git a/test/CodeGenCXX/delete.cpp b/test/CodeGenCXX/delete.cpp
index 8ad76f8..5a88f9f 100644
--- a/test/CodeGenCXX/delete.cpp
+++ b/test/CodeGenCXX/delete.cpp
@@ -30,7 +30,7 @@
 // PR5102
 template <typename T>
 class A {
-  operator T *() const;
+  public: operator T *() const;
 };
 
 void f() {