From: Douglas Gregor Date: Thu, 20 Jan 2011 01:32:05 +0000 (+0000) Subject: When building a user-defined conversion sequence, keep track of the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=83eecbefa4931b95231c9f2a61fb7b9b15e00eec;p=clang When building a user-defined conversion sequence, keep track of the declaration that name lookup actually found, so that we can use it for access checking later on. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123867 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index 56b0f53bc6..fa3c94b0ac 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -231,6 +231,11 @@ namespace clang { /// user-defined conversion. FunctionDecl* ConversionFunction; + /// \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; + void DebugPrint() const; }; diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 2a339142ca..c497d7278f 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -1691,6 +1691,7 @@ static ExprResult BuildCXXCastArgument(Sema &S, QualType Ty, CastKind Kind, CXXMethodDecl *Method, + NamedDecl *FoundDecl, Expr *From) { switch (Kind) { default: assert(0 && "Unhandled cast kind!"); @@ -1717,8 +1718,7 @@ static ExprResult BuildCXXCastArgument(Sema &S, assert(!From->getType()->isPointerType() && "Arg can't have pointer type!"); // Create an implicit call expr that calls it. - // FIXME: pass the FoundDecl for the user-defined conversion here - ExprResult Result = S.BuildCXXMemberCallExpr(From, Method, Method); + ExprResult Result = S.BuildCXXMemberCallExpr(From, FoundDecl, Method); if (Result.isInvalid()) return ExprError(); @@ -1779,7 +1779,8 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, = BuildCXXCastArgument(*this, From->getLocStart(), ToType.getNonReferenceType(), - CastKind, cast(FD), + CastKind, cast(FD), + ICS.UserDefined.FoundConversionFunction, From); if (CastArg.isInvalid()) diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index ac106883a3..c6150d91ec 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -2146,6 +2146,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, User.EllipsisConversion = false; } User.ConversionFunction = Constructor; + User.FoundConversionFunction = Best->FoundDecl.getDecl(); User.After.setAsIdentityConversion(); User.After.setFromType(ThisType->getAs()->getPointeeType()); User.After.setAllToTypes(ToType); @@ -2160,6 +2161,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.EllipsisConversion = false; // C++ [over.ics.user]p2: @@ -2876,6 +2878,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.EllipsisConversion = false; assert(ICS.UserDefined.After.ReferenceBinding && ICS.UserDefined.After.DirectBinding && @@ -4106,6 +4109,8 @@ 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.After = Candidate.Conversions[0].UserDefined.Before; Candidate.Conversions[0].UserDefined.After.setAsIdentityConversion(); diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp index 565fcefe65..e4e9ff0496 100644 --- a/test/CXX/class.access/p4.cpp +++ b/test/CXX/class.access/p4.cpp @@ -488,3 +488,13 @@ namespace test21 { A::Inner i; // expected-error {{'Inner' is a private member}} } } + +namespace rdar8876150 { + struct A { operator bool(); }; + struct B : private A { using A::operator bool; }; + + bool f() { + B b; + return !b; + } +}