[cfe-commits] [PATCH] Add smarter sorting of overload candidates that failed template deduction

Kaelyn Uhrain rikka at google.com
Thu Sep 8 16:43:22 PDT 2011


Given a file tmp.cpp containing:

void exit(int);
void exit(float);

template <typename T>
struct Identity {
 typedef T type;
};

template <class T1, class T2, class R>
void f(const T1* obj, R (T2::*member)() const);

template <class T1, class T2, class R>
void f( T1* obj, R (T2::*member)());

template <class R>
void f(R (*function)());

template <class T1, class T2, class R, class P1>
void f(const T1* obj, R (T2::*member)(P1) const, typename Identity<P1>::type
p1);

template <class T1, class T2, class R, class P1>
void f( T1* obj, R (T2::*member)(P1) , typename Identity<P1>::type p1);

template <class R, class P1>
void f(R (*function)(P1), typename Identity<P1>::type p1);

template <class T1, class T2, class R, class P1, class P2>
void f(const T1* obj, R (T2::*member)(P1, P2) const, typename
Identity<P1>::type p1, typename Identity<P2>::type p2);

template <class T1, class T2, class R, class P1, class P2>
void f( T1* obj, R (T2::*member)(P1, P2) , typename Identity<P1>::type p1,
typename Identity<P2>::type p2);

template <class R, class P1, class P2>
void f(R (*function)(P1, P2), typename Identity<P1>::type p1, typename
Identity<P2>::type p2);

void test() {
 f(exit, 0);
}


When Clang emits the error about not finding a match for that call to f
because exit is an overloaded function, Clang currently emits notes for all
of the function template candidates in lexical order, to where the "closest"
failing match is the 6th note of 9 with 3 candidates that require a
different number of arguments listed before it:

tmp.cpp:37:2: error: no matching function for call to 'f'
 f(exit, 0);
 ^
tmp.cpp:10:6: note: candidate template ignored: failed template argument
deduction
void f(const T1* obj, R (T2::*member)() const);
     ^
tmp.cpp:13:6: note: candidate template ignored: failed template argument
deduction
void f( T1* obj, R (T2::*member)());
     ^
tmp.cpp:16:6: note: candidate function template not viable: requires 1
argument, but 2 were provided
void f(R (*function)());
     ^
tmp.cpp:19:6: note: candidate function template not viable: requires 3
arguments, but 2 were provided
void f(const T1* obj, R (T2::*member)(P1) const, typename Identity<P1>::type
p1);
     ^
tmp.cpp:22:6: note: candidate function template not viable: requires 3
arguments, but 2 were provided
void f( T1* obj, R (T2::*member)(P1) , typename Identity<P1>::type p1);
     ^
tmp.cpp:25:6: note: candidate template ignored: couldn't infer template
argument 'R'
void f(R (*function)(P1), typename Identity<P1>::type p1);
     ^
tmp.cpp:28:6: note: candidate function template not viable: requires 4
arguments, but 2 were provided
void f(const T1* obj, R (T2::*member)(P1, P2) const, typename
Identity<P1>::type p1, typename Identity<P2>::type p2);
     ^
tmp.cpp:31:6: note: candidate function template not viable: requires 4
arguments, but 2 were provided
void f( T1* obj, R (T2::*member)(P1, P2) , typename Identity<P1>::type p1,
typename Identity<P2>::type p2);
     ^
tmp.cpp:34:6: note: candidate function template not viable: requires 3
arguments, but 2 were provided
void f(R (*function)(P1, P2), typename Identity<P1>::type p1, typename
Identity<P2>::type p2);
     ^
1 error generated.


This small patch adds rankings to the different types of template deduction
failure (all of the OverloadCandidates above have a base FailureKind of
ovl_fail_bad_deduction), so that e.g. a candidate where a template argument
could not be inferred is listed before a candidate that requires the wrong
number of arguments. So for the above code example, the output becomes:

tmp.cpp:37:2: error: no matching function for call to 'f'
 f(exit, 0);
 ^
tmp.cpp:25:6: note: candidate template ignored: couldn't infer template
argument 'R'
void f(R (*function)(P1), typename Identity<P1>::type p1);
     ^
tmp.cpp:10:6: note: candidate template ignored: failed template argument
deduction
void f(const T1* obj, R (T2::*member)() const);
     ^
tmp.cpp:13:6: note: candidate template ignored: failed template argument
deduction
void f( T1* obj, R (T2::*member)());
     ^
tmp.cpp:16:6: note: candidate function template not viable: requires 1
argument, but 2 were provided
void f(R (*function)());
     ^
tmp.cpp:19:6: note: candidate function template not viable: requires 3
arguments, but 2 were provided
void f(const T1* obj, R (T2::*member)(P1) const, typename Identity<P1>::type
p1);
     ^
tmp.cpp:22:6: note: candidate function template not viable: requires 3
arguments, but 2 were provided
void f( T1* obj, R (T2::*member)(P1) , typename Identity<P1>::type p1);
     ^
tmp.cpp:28:6: note: candidate function template not viable: requires 4
arguments, but 2 were provided
void f(const T1* obj, R (T2::*member)(P1, P2) const, typename
Identity<P1>::type p1, typename Identity<P2>::type p2);
     ^
tmp.cpp:31:6: note: candidate function template not viable: requires 4
arguments, but 2 were provided
void f( T1* obj, R (T2::*member)(P1, P2) , typename Identity<P1>::type p1,
typename Identity<P2>::type p2);
     ^
tmp.cpp:34:6: note: candidate function template not viable: requires 3
arguments, but 2 were provided
void f(R (*function)(P1, P2), typename Identity<P1>::type p1, typename
Identity<P2>::type p2);
     ^
1 error generated.


While the text of the note still isn't particularly useful for figuring out
what failed, it at least gives a little better clue as to where the problem
lies (in this example, the problem is rooted in there being two different
single-argument declarations of "exit"). Feedback is both welcome and
desired, especially on the ranking of the different types of deduction
failures.

Cheers,
Kaelyn
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20110908/5df62fae/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: template-overload-sorting.diff
Type: text/x-diff
Size: 1580 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20110908/5df62fae/attachment.diff>


More information about the cfe-commits mailing list