DR 495 changed the order of these rules. Tested x86_64-pc-linux-gnu, applying to trunk.
commit dc49a72a22b10b39edc054414537bda44ce82546 Author: Jason Merrill <ja...@redhat.com> Date: Thu Nov 10 14:59:15 2011 -0500
PR c++/51079, DR 495 * call.c (joust): Check the second conversion sequence before checking templates. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 578905e..e81950c 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -8109,6 +8109,22 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn) if (winner) return winner; + /* DR 495 moved this tiebreaker above the template ones. */ + /* or, if not that, + the context is an initialization by user-defined conversion (see + _dcl.init_ and _over.match.user_) and the standard conversion + sequence from the return type of F1 to the destination type (i.e., + the type of the entity being initialized) is a better conversion + sequence than the standard conversion sequence from the return type + of F2 to the destination type. */ + + if (cand1->second_conv) + { + winner = compare_ics (cand1->second_conv, cand2->second_conv); + if (winner) + return winner; + } + /* or, if not that, F1 is a non-template function and F2 is a template function specialization. */ @@ -8137,21 +8153,6 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn) return winner; } - /* or, if not that, - the context is an initialization by user-defined conversion (see - _dcl.init_ and _over.match.user_) and the standard conversion - sequence from the return type of F1 to the destination type (i.e., - the type of the entity being initialized) is a better conversion - sequence than the standard conversion sequence from the return type - of F2 to the destination type. */ - - if (cand1->second_conv) - { - winner = compare_ics (cand1->second_conv, cand2->second_conv); - if (winner) - return winner; - } - /* Check whether we can discard a builtin candidate, either because we have two identical ones or matching builtin and non-builtin candidates. diff --git a/gcc/testsuite/g++.dg/template/conv12.C b/gcc/testsuite/g++.dg/template/conv12.C new file mode 100644 index 0000000..e6af054 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv12.C @@ -0,0 +1,25 @@ +// PR c++/51079 + +#if __cplusplus > 199711L +struct C1 +{ + template <class T> + operator T() = delete; // { dg-message "declared here" "" { target c++11 } } + operator bool() { return false; } +} c1; + +int ic1 = c1; // { dg-error "deleted" "" { target c++11 } } +int ac1 = c1 + c1; // { dg-error "deleted" "" { target c++11 } } +#endif + +struct C2 +{ +private: + template <class T> + operator T(); // { dg-error "private" } +public: + operator bool() { return false; } +} c2; + +int ic2 = c2; // { dg-error "" } +int ac2 = c2 + c2; // { dg-error "" }