From ca82a82082edc982a1fb5fcfef2dd2c8cf9bc824 Mon Sep 17 00:00:00 2001 From: John McCall Date: Wed, 21 Sep 2011 08:36:56 +0000 Subject: [PATCH] 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 --- include/clang/Sema/Overload.h | 2 +- lib/Sema/SemaAccess.cpp | 3 +-- lib/Sema/SemaExprCXX.cpp | 4 +++- lib/Sema/SemaOverload.cpp | 9 ++++----- test/CXX/class.access/p6.cpp | 22 ++++++++++++++++++++++ test/CodeGenCXX/delete.cpp | 2 +- 6 files changed, 32 insertions(+), 10 deletions(-) diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index 9d26202839..214f8c0eb2 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -256,7 +256,7 @@ namespace clang { /// \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 e501a393d1..a2d078b12c 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -1551,8 +1551,7 @@ Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc, Found.getAccess() == AS_public) return AR_accessible; - const RecordType *RT = ObjectExpr->getType()->getAs(); - assert(RT && "found member operator but object expr not of record type"); + const RecordType *RT = ObjectExpr->getType()->castAs(); CXXRecordDecl *NamingClass = cast(RT->getDecl()); AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found, diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 98f96bc68d..1741bdb1ef 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2065,7 +2065,7 @@ static ExprResult BuildCXXCastArgument(Sema &S, QualType Ty, CastKind Kind, CXXMethodDecl *Method, - NamedDecl *FoundDecl, + DeclAccessPair FoundDecl, Expr *From) { switch (Kind) { default: assert(0 && "Unhandled cast kind!"); @@ -2096,6 +2096,8 @@ static ExprResult BuildCXXCastArgument(Sema &S, 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 c084f76a50..806fd39fee 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -2509,7 +2509,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, User.EllipsisConversion = false; } User.ConversionFunction = Constructor; - User.FoundConversionFunction = Best->FoundDecl.getDecl(); + User.FoundConversionFunction = Best->FoundDecl; User.After.setAsIdentityConversion(); User.After.setFromType(ThisType->getAs()->getPointeeType()); User.After.setAllToTypes(ToType); @@ -2526,7 +2526,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, // 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 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS, 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 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, 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 fe3304a222..932b4f42f2 100644 --- a/test/CXX/class.access/p6.cpp +++ b/test/CXX/class.access/p6.cpp @@ -168,3 +168,25 @@ namespace test7 { 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 8ad76f8532..5a88f9f924 100644 --- a/test/CodeGenCXX/delete.cpp +++ b/test/CodeGenCXX/delete.cpp @@ -30,7 +30,7 @@ void t4(T *t) { // PR5102 template class A { - operator T *() const; + public: operator T *() const; }; void f() { -- 2.40.0