Index: lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- lib/Sema/SemaTemplateDeduction.cpp +++ lib/Sema/SemaTemplateDeduction.cpp @@ -4178,34 +4178,24 @@ // 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, which seems to match - // existing practice. + // C++98/03 doesn't have this provision but we've extended DR532 to cover + // it as wording was broken prior to it. SmallVector Args1; - unsigned Skip1 = 0, Skip2 = 0; unsigned NumComparedArguments = NumCallArguments1; if (!Method2 && Method1 && !Method1->isStatic()) { - if (S.getLangOpts().CPlusPlus11) { - // Compare 'this' from Method1 against first parameter from Method2. - AddImplicitObjectParameterType(S.Context, Method1, Args1); - ++NumComparedArguments; - } else - // Ignore first parameter from Method2. - ++Skip2; + // Compare 'this' from Method1 against first parameter from Method2. + AddImplicitObjectParameterType(S.Context, Method1, Args1); + ++NumComparedArguments; } else if (!Method1 && Method2 && !Method2->isStatic()) { - if (S.getLangOpts().CPlusPlus11) - // Compare 'this' from Method2 against first parameter from Method1. - AddImplicitObjectParameterType(S.Context, Method2, Args2); - else - // Ignore first parameter from Method1. - ++Skip1; + // Compare 'this' from Method2 against first parameter from Method1. + AddImplicitObjectParameterType(S.Context, Method2, Args2); } - Args1.insert(Args1.end(), Proto1->param_type_begin() + Skip1, + Args1.insert(Args1.end(), Proto1->param_type_begin(), Proto1->param_type_end()); - Args2.insert(Args2.end(), Proto2->param_type_begin() + Skip2, + Args2.insert(Args2.end(), Proto2->param_type_begin(), Proto2->param_type_end()); // C++ [temp.func.order]p5: Index: test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp =================================================================== --- test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -// expected-no-diagnostics - -// Core DR 532. -namespace PR8130 { - struct A { }; - - template struct B { - template int &operator*(R&); - }; - - template float &operator*(T&, R&); - void test() { - A a; - B b; - int &ir = b * a; - } -} - -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; } - template static int g(T*) { return 1; } - }; - void f() { - A a; - int **p; - a.g(p); - } -} - -namespace PR17075 { - template struct V {}; - struct S { template S &operator>>(T &t) = delete; }; - template S &operator>>(S &s, V &v); - void f(S s, V v) { s >> v; } -} Index: test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp =================================================================== --- test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp +++ test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp @@ -1,18 +1,20 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s // expected-no-diagnostics -namespace DeduceVsMember { - template - struct X { - template - int &operator==(const U& other) const; - }; +// Core DR 532. +namespace PR8130 { + struct A { }; - template - float &operator==(const T&, const X&); + template struct B { + template int &operator*(R&); + }; - void test(X xi, X xf) { - float& ir = (xi == xf); + template float &operator*(T&, R&); + void test() { + A a; + B b; + int &ir = b * a; } } @@ -27,3 +29,27 @@ a.g(p); } } + +#if __cplusplus >= 201103L +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 PR17075 { + template struct V {}; + struct S { template S &operator>>(T &t) = delete; }; + template S &operator>>(S &s, V &v); + void f(S s, V v) { s >> v; } +} +#endif