diff options
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 62 |
1 files changed, 30 insertions, 32 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 06b5fcb318..2a2521a32c 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -622,8 +622,36 @@ Sema::IsStandardConversion(Expr* From, QualType ToType, // array-to-pointer conversion, or function-to-pointer conversion // (C++ 4p1). - DeclAccessPair AccessPair; - + if (FromType == Context.OverloadTy) { + DeclAccessPair AccessPair; + if (FunctionDecl *Fn + = ResolveAddressOfOverloadedFunction(From, ToType, false, + AccessPair)) { + // We were able to resolve the address of the overloaded function, + // so we can convert to the type of that function. + FromType = Fn->getType(); + if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) { + if (!Method->isStatic()) { + Type *ClassType + = Context.getTypeDeclType(Method->getParent()).getTypePtr(); + FromType = Context.getMemberPointerType(FromType, ClassType); + } + } + + // If the "from" expression takes the address of the overloaded + // function, update the type of the resulting expression accordingly. + if (FromType->getAs<FunctionType>()) + if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(From->IgnoreParens())) + if (UnOp->getOpcode() == UnaryOperator::AddrOf) + FromType = Context.getPointerType(FromType); + + // Check that we've computed the proper type after overload resolution. + assert(Context.hasSameType(FromType, + FixOverloadedFunctionReference(From, AccessPair, Fn)->getType())); + } else { + return false; + } + } // Lvalue-to-rvalue conversion (C++ 4.1): // An lvalue (3.10) of a non-function, non-array type T can be // converted to an rvalue. @@ -668,36 +696,6 @@ Sema::IsStandardConversion(Expr* From, QualType ToType, // type "pointer to T." The result is a pointer to the // function. (C++ 4.3p1). FromType = Context.getPointerType(FromType); - } else if (From->getType() == Context.OverloadTy) { - if (FunctionDecl *Fn - = ResolveAddressOfOverloadedFunction(From, ToType, false, - AccessPair)) { - // Address of overloaded function (C++ [over.over]). - SCS.First = ICK_Function_To_Pointer; - - // We were able to resolve the address of the overloaded function, - // so we can convert to the type of that function. - FromType = Fn->getType(); - if (ToType->isLValueReferenceType()) - FromType = Context.getLValueReferenceType(FromType); - else if (ToType->isRValueReferenceType()) - FromType = Context.getRValueReferenceType(FromType); - else if (ToType->isMemberPointerType()) { - // Resolve address only succeeds if both sides are member pointers, - // but it doesn't have to be the same class. See DR 247. - // Note that this means that the type of &Derived::fn can be - // Ret (Base::*)(Args) if the fn overload actually found is from the - // base class, even if it was brought into the derived class via a - // using declaration. The standard isn't clear on this issue at all. - CXXMethodDecl *M = cast<CXXMethodDecl>(Fn); - FromType = Context.getMemberPointerType(FromType, - Context.getTypeDeclType(M->getParent()).getTypePtr()); - } else { - FromType = Context.getPointerType(FromType); - } - } else { - return false; - } } else { // We don't require any conversions for the first step. SCS.First = ICK_Identity; |