diff options
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 29 | ||||
-rw-r--r-- | test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp | 15 |
2 files changed, 28 insertions, 16 deletions
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 8a30ba2884..b97a12a2cb 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -3651,26 +3651,23 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T, llvm::SmallBitVector &Deduced); /// \brief If this is a non-static member function, -static void MaybeAddImplicitObjectParameterType(ASTContext &Context, +static void AddImplicitObjectParameterType(ASTContext &Context, CXXMethodDecl *Method, SmallVectorImpl<QualType> &ArgTypes) { - if (Method->isStatic()) - return; - - // C++ [over.match.funcs]p4: + // C++11 [temp.func.order]p3: + // [...] The new parameter is of type "reference to cv A," where cv are + // the cv-qualifiers of the function template (if any) and A is + // the class of which the function template is a member. // - // For non-static member functions, the type of the implicit - // object parameter is - // - "lvalue reference to cv X" for functions declared without a - // ref-qualifier or with the & ref-qualifier - // - "rvalue reference to cv X" for functions declared with the - // && ref-qualifier - // - // FIXME: We don't have ref-qualifiers yet, so we don't do that part. + // The standard doesn't say explicitly, but we pick the appropriate kind of + // reference type based on [over.match.funcs]p4. QualType ArgTy = Context.getTypeDeclType(Method->getParent()); ArgTy = Context.getQualifiedType(ArgTy, Qualifiers::fromCVRMask(Method->getTypeQualifiers())); - ArgTy = Context.getLValueReferenceType(ArgTy); + if (Method->getRefQualifier() == RQ_RValue) + ArgTy = Context.getRValueReferenceType(ArgTy); + else + ArgTy = Context.getLValueReferenceType(ArgTy); ArgTypes.push_back(ArgTy); } @@ -3730,14 +3727,14 @@ static bool isAtLeastAsSpecializedAs(Sema &S, SmallVector<QualType, 4> Args1; unsigned Skip1 = !S.getLangOpts().CPlusPlus0x && IsNonStatic2 && !Method1; if (S.getLangOpts().CPlusPlus0x && IsNonStatic1 && !Method2) - MaybeAddImplicitObjectParameterType(S.Context, Method1, Args1); + AddImplicitObjectParameterType(S.Context, Method1, Args1); Args1.insert(Args1.end(), Proto1->arg_type_begin() + Skip1, Proto1->arg_type_end()); SmallVector<QualType, 4> Args2; Skip2 = !S.getLangOpts().CPlusPlus0x && IsNonStatic1 && !Method2; if (S.getLangOpts().CPlusPlus0x && IsNonStatic2 && !Method1) - MaybeAddImplicitObjectParameterType(S.Context, Method2, Args2); + AddImplicitObjectParameterType(S.Context, Method2, Args2); Args2.insert(Args2.end(), Proto2->arg_type_begin() + Skip2, Proto2->arg_type_end()); diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp index 9dd683261e..4d56653845 100644 --- a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp +++ b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp @@ -16,6 +16,21 @@ namespace PR8130 { } } +namespace OperatorWithRefQualifier { + struct A { }; + template<class T> struct B { + template<class R> int &operator*(R&) &&; + }; + + template<class T, class R> float &operator*(T&&, R&); + void test() { + A a; + B<A> b; + float &ir = b * a; + int &ir2 = B<A>() * a; + } +} + namespace OrderWithStaticMember { struct A { template<class T> int g(T**, int=0) { return 0; } |