From 9cef0064da0fe93cf60cc351d28ddf2e95fba0b3 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Wed, 19 Sep 2012 23:27:04 +0000 Subject: [PATCH] Fix function template partial ordering rules for static vs. non-static functions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164263 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateDeduction.cpp | 21 +++++++++++-------- .../temp.fct/temp.func.order/p3-0x.cpp | 12 +++++++++++ .../temp.fct/temp.func.order/p3.cpp | 12 +++++++++++ 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 0fdcd1416f..8a30ba2884 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -3711,7 +3711,7 @@ static bool isAtLeastAsSpecializedAs(Sema &S, IsNonStatic1 = Method1 && !Method1->isStatic(); IsNonStatic2 = Method2 && !Method2->isStatic(); - // C++0x [temp.func.order]p3: + // C++11 [temp.func.order]p3: // [...] If only one of the function templates is a non-static // member, that function template is considered to have a new // first parameter inserted in its function parameter list. The @@ -3719,21 +3719,24 @@ static bool isAtLeastAsSpecializedAs(Sema &S, // the cv-qualifiers of the function template (if any) and A is // the class of which the function template is a member. // + // Note that we interpret this to mean "if one of the function + // templates is a non-static member and the other is a non-member"; + // otherwise, the ordering rules for static functions against non-static + // functions don't make any sense. + // // C++98/03 doesn't have this provision, so instead we drop the - // first argument of the free function or static member, which - // seems to match existing practice. + // first argument of the free function, which seems to match + // existing practice. SmallVector Args1; - unsigned Skip1 = !S.getLangOpts().CPlusPlus0x && - IsNonStatic2 && !IsNonStatic1; - if (S.getLangOpts().CPlusPlus0x && IsNonStatic1 && !IsNonStatic2) + unsigned Skip1 = !S.getLangOpts().CPlusPlus0x && IsNonStatic2 && !Method1; + if (S.getLangOpts().CPlusPlus0x && IsNonStatic1 && !Method2) MaybeAddImplicitObjectParameterType(S.Context, Method1, Args1); Args1.insert(Args1.end(), Proto1->arg_type_begin() + Skip1, Proto1->arg_type_end()); SmallVector Args2; - Skip2 = !S.getLangOpts().CPlusPlus0x && - IsNonStatic1 && !IsNonStatic2; - if (S.getLangOpts().CPlusPlus0x && IsNonStatic2 && !IsNonStatic1) + Skip2 = !S.getLangOpts().CPlusPlus0x && IsNonStatic1 && !Method2; + if (S.getLangOpts().CPlusPlus0x && IsNonStatic2 && !Method1) MaybeAddImplicitObjectParameterType(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 63909fb7cd..9dd683261e 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 @@ -15,3 +15,15 @@ namespace PR8130 { int &ir = b * a; } } + +namespace OrderWithStaticMember { + struct A { + template int g(T**, int=0) { return 0; } + template static int g(T*) { return 1; } + }; + void f() { + A a; + int **p; + a.g(p); + } +} diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp index 2ffdd9579e..815f8bfb56 100644 --- a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp +++ b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp @@ -14,3 +14,15 @@ namespace DeduceVsMember { float& ir = (xi == xf); } } + +namespace OrderWithStaticMember { + struct A { + template int g(T**, int=0) { return 0; } + template static int g(T*) { return 1; } + }; + void f() { + A a; + int **p; + a.g(p); + } +} -- 2.40.0