From: Eli Friedman Date: Wed, 19 Sep 2012 23:52:13 +0000 (+0000) Subject: Fix a small FIXME involving template partial ordering and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=407c8470d50be8edaae7ed39a3139adf35af2921;p=clang Fix a small FIXME involving template partial ordering and member function templates with an rvalue ref qualifier. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164267 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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 &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 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 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 struct B { + template int &operator*(R&) &&; + }; + + template float &operator*(T&&, R&); + void test() { + A a; + B b; + float &ir = b * a; + int &ir2 = B() * a; + } +} + namespace OrderWithStaticMember { struct A { template int g(T**, int=0) { return 0; }