]> granicus.if.org Git - clang/commitdiff
When building a user-defined conversion sequence, keep track of the
authorDouglas Gregor <dgregor@apple.com>
Thu, 20 Jan 2011 01:32:05 +0000 (01:32 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 20 Jan 2011 01:32:05 +0000 (01:32 +0000)
declaration that name lookup actually found, so that we can use it for
access checking later on. Fixes <rdar://problem/8876150>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123867 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Overload.h
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaOverload.cpp
test/CXX/class.access/p4.cpp

index 56b0f53bc61ea3308e196da7fc9cdd1f630a6f5a..fa3c94b0ac28dfa47f1e43752a7290b060bd1453 100644 (file)
@@ -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;
   };
 
index 2a339142ca4acd16c0839cd3ba48739e8a21f73e..c497d7278fc0aa4cf29a50c534fcc07e95f72cca 100644 (file)
@@ -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<CXXMethodDecl>(FD), 
+                               CastKind, cast<CXXMethodDecl>(FD),
+                               ICS.UserDefined.FoundConversionFunction,
                                From);
 
       if (CastArg.isInvalid())
index ac106883a3502ac2f7bc91ccad03678e15a60e79..c6150d91ecefdff50ccfff64993d97b6ba4f6bff 100644 (file)
@@ -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<PointerType>()->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();
index 565fcefe65a60bb9b34599d46905216213e640ea..e4e9ff0496c293d0ed0bef29a0cf8501db838736 100644 (file)
@@ -488,3 +488,13 @@ namespace test21 {
     A<int>::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;
+  }
+}