From 42e9f80bf4f6a38733c221c03a512c432cdb784f Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 11 May 2020 15:39:44 -0400 Subject: [PATCH] c++: Better diagnostic in converted const expr. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This improves the diagnostic from error: could not convert ‘((A<>*)(void)0)->A<>::e’ from ‘’ to ‘bool’ to error: cannot convert ‘A<>::e’ from type ‘void (A<>::)()’ to type ‘bool’ gcc/cp/ChangeLog 2020-05-11 Jason Merrill * call.c (implicit_conversion_error): Split out from... (perform_implicit_conversion_flags): ...here. (build_converted_constant_expr_internal): Use it. --- gcc/cp/ChangeLog | 6 ++++ gcc/cp/call.c | 41 +++++++++++++---------- gcc/testsuite/g++.dg/cpp0x/noexcept30.C | 2 +- gcc/testsuite/g++.dg/cpp0x/noexcept58.C | 9 +++++ gcc/testsuite/g++.dg/template/crash87.C | 2 +- gcc/testsuite/g++.dg/template/nontype13.C | 2 +- 6 files changed, 42 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/noexcept58.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3f135064887..f2814c3b037 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2020-05-11 Jason Merrill + + * call.c (implicit_conversion_error): Split out from... + (perform_implicit_conversion_flags): ...here. + (build_converted_constant_expr_internal): Use it. + 2020-05-11 Jason Merrill PR c++/90748 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index aca12c74c25..85d670f52f9 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4282,6 +4282,28 @@ build_user_type_conversion (tree totype, tree expr, int flags, return ret; } +/* Give a helpful diagnostic when implicit_conversion fails. */ + +static void +implicit_conversion_error (location_t loc, tree type, tree expr) +{ + tsubst_flags_t complain = tf_warning_or_error; + + /* If expr has unknown type, then it is an overloaded function. + Call instantiate_type to get good error messages. */ + if (TREE_TYPE (expr) == unknown_type_node) + instantiate_type (type, expr, complain); + else if (invalid_nonstatic_memfn_p (loc, expr, complain)) + /* We gave an error. */; + else + { + range_label_for_type_mismatch label (TREE_TYPE (expr), type); + gcc_rich_location rich_loc (loc, &label); + error_at (&rich_loc, "could not convert %qE from %qH to %qI", + expr, TREE_TYPE (expr), type); + } +} + /* Worker for build_converted_constant_expr. */ static tree @@ -4397,8 +4419,7 @@ build_converted_constant_expr_internal (tree type, tree expr, else { if (complain & tf_error) - error_at (loc, "could not convert %qE from %qH to %qI", expr, - TREE_TYPE (expr), type); + implicit_conversion_error (loc, type, expr); expr = error_mark_node; } @@ -11845,21 +11866,7 @@ perform_implicit_conversion_flags (tree type, tree expr, if (!conv) { if (complain & tf_error) - { - /* If expr has unknown type, then it is an overloaded function. - Call instantiate_type to get good error messages. */ - if (TREE_TYPE (expr) == unknown_type_node) - instantiate_type (type, expr, complain); - else if (invalid_nonstatic_memfn_p (loc, expr, complain)) - /* We gave an error. */; - else - { - range_label_for_type_mismatch label (TREE_TYPE (expr), type); - gcc_rich_location rich_loc (loc, &label); - error_at (&rich_loc, "could not convert %qE from %qH to %qI", - expr, TREE_TYPE (expr), type); - } - } + implicit_conversion_error (loc, type, expr); expr = error_mark_node; } else if (processing_template_decl && conv->kind != ck_identity) diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept30.C b/gcc/testsuite/g++.dg/cpp0x/noexcept30.C index 6a9f7821092..1075c69a491 100644 --- a/gcc/testsuite/g++.dg/cpp0x/noexcept30.C +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept30.C @@ -5,7 +5,7 @@ template struct F { template - void f() noexcept(&F::template f) {} // { dg-error "exception specification|convert" } + void f() noexcept(&F::template f) {} // { dg-error "exception specification|convert|resolve" } }; int main () { diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept58.C b/gcc/testsuite/g++.dg/cpp0x/noexcept58.C new file mode 100644 index 00000000000..0a145e030a5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept58.C @@ -0,0 +1,9 @@ +// PR c++/90748 +// { dg-do compile { target c++11 } } + +template class A +{ + void e (); + bool f (int() noexcept(e)); // { dg-error "::e" } +}; +A<> b; diff --git a/gcc/testsuite/g++.dg/template/crash87.C b/gcc/testsuite/g++.dg/template/crash87.C index af81edbfd80..7da6623612a 100644 --- a/gcc/testsuite/g++.dg/template/crash87.C +++ b/gcc/testsuite/g++.dg/template/crash87.C @@ -17,7 +17,7 @@ template class BUG2 : BUG { public: - typedef BUG1_5 ptr; // { dg-error "convert" } + typedef BUG1_5 ptr; // { dg-error "BUG::name" } }; int main() diff --git a/gcc/testsuite/g++.dg/template/nontype13.C b/gcc/testsuite/g++.dg/template/nontype13.C index 3250109aa4a..4d6b323ed64 100644 --- a/gcc/testsuite/g++.dg/template/nontype13.C +++ b/gcc/testsuite/g++.dg/template/nontype13.C @@ -11,7 +11,7 @@ struct Dummy template void tester() { - bar()(); // { dg-error "constant|template|convert" } + bar()(); // { dg-error "constant|template|convert|member function" } } template struct bar -- 2.30.2