C++: special-case single non-viable candidate (more PR c++/85110)
commitb78e49d1ddf1a09e16152353b41bf7c0b44d6405
authordmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 12 Sep 2018 18:50:08 +0000 (12 18:50 +0000)
committerdmalcolm <dmalcolm@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 12 Sep 2018 18:50:08 +0000 (12 18:50 +0000)
tree4e4772fd56335a5477fd9d79405d21633523558c
parent0d9500245456e92c9a266f8c582a46474effc5d8
C++: special-case single non-viable candidate (more PR c++/85110)

I broke out the "no viable candidates" case in build_new_method_call_1
into a subroutine, and added special-case handling for when there's
a single non-viable candidate where there's an argument conversion
error.  I turned the error-handling from convert_for_assignment into
a subroutine, calling it from this new special-case.

This converts:

demo.cc: In function 'int test_4(int, const char*, float)':
demo.cc:5:44: error: no matching function for call to 's4::member_1(int&, const char*&, float&)'
5 |   return s4::member_1 (first, second, third);
  |                                            ^
demo.cc:1:24: note: candidate: 'static int s4::member_1(int, const char**, float)'
1 | struct s4 { static int member_1 (int one, const char **two, float three); };
  |                        ^~~~~~~~
demo.cc:1:56: note:   no known conversion for argument 2 from 'const char*' to 'const char**'
1 | struct s4 { static int member_1 (int one, const char **two, float three); };
  |                                           ~~~~~~~~~~~~~^~~

to:

demo.cc: In function 'int test_4(int, const char*, float)':
demo.cc:5:31: error: cannot convert 'const char*' to 'const char**'
5 |   return s4::member_1 (first, second, third);
  |                               ^~~~~~
  |                               |
  |                               const char*
demo.cc:1:56: note:   initializing argument 2 of 'static int s4::member_1(int, const char**, float)'
1 | struct s4 { static int member_1 (int one, const char **two, float three); };
  |                                           ~~~~~~~~~~~~~^~~

thus highlighting the problematic argument at the callsite (and its type).

gcc/cp/ChangeLog:
PR c++/85110
* call.c (struct conversion_info): Add "loc" field.
(arg_conversion_rejection): Add "loc" param, using it to
initialize the new field.
(bad_arg_conversion_rejection): Likewise.
(explicit_conversion_rejection): Initialize the new field to
UNKNOWN_LOCATION.
(template_conversion_rejection): Likewise.
(add_function_candidate): Pass on the argument location to the new
param of arg_conversion_rejection.
(add_conv_candidate): Likewise.
(build_builtin_candidate): Likewise.
(build_user_type_conversion_1): Likewise.
(single_z_candidate): New function.
(maybe_get_bad_conversion_for_unmatched_call): New function.
(complain_about_bad_argument): New function, based on part of
convert_for_assignment.
(build_new_method_call_1): Split out handling of the "no viable
candidates" case into...
(complain_about_no_candidates_for_method_call): ...this new
function, and use the new functions above to special-case the
handling of a single non-viable candidate due to a bad argument.
* cp-tree.h (complain_about_bad_argument): New decl.
* typeck.c (convert_for_assignment): Split out one error-handling
case into complain_about_bad_argument.

gcc/testsuite/ChangeLog:
PR c++/85110
* g++.dg/cpp0x/explicit4.C: Update expected output to reflect
special-casing of diagnostic for a single non-viable candidate due
to a bad argument.
* g++.dg/diagnostic/param-type-mismatch-2.C: Likewise.
Add test coverage for an unmatched overloaded operator.
* g++.dg/expr/pmf-1.C: Likewise.
* g++.old-deja/g++.bugs/900330_02.C: Likewise.
* g++.old-deja/g++.jason/conversion11.C: Likewise.
* g++.old-deja/g++.law/arg11.C: Likewise.
* g++.old-deja/g++.law/arm9.C: Likewise.
* g++.old-deja/g++.robertl/eb131.C: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@264250 138bc75d-0d04-0410-961f-82ee72b054a4
13 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/explicit4.C
gcc/testsuite/g++.dg/diagnostic/param-type-mismatch-2.C
gcc/testsuite/g++.dg/expr/pmf-1.C
gcc/testsuite/g++.old-deja/g++.bugs/900330_02.C
gcc/testsuite/g++.old-deja/g++.jason/conversion11.C
gcc/testsuite/g++.old-deja/g++.law/arg11.C
gcc/testsuite/g++.old-deja/g++.law/arm9.C
gcc/testsuite/g++.old-deja/g++.robertl/eb131.C