summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-05-11 15:39:44 -0400
committerJason Merrill <jason@redhat.com>2020-05-11 15:41:15 -0400
commit42e9f80bf4f6a38733c221c03a512c432cdb784f (patch)
tree4d97c0e9a64f2b380606b163b844722295161983
parentf981395c220c9afd73be138294946e085e64af78 (diff)
c++: Better diagnostic in converted const expr.
This improves the diagnostic from error: could not convert ‘((A<>*)(void)0)->A<>::e’ from ‘<unresolved overloaded function type>’ to ‘bool’ to error: cannot convert ‘A<>::e’ from type ‘void (A<>::)()’ to type ‘bool’ gcc/cp/ChangeLog 2020-05-11 Jason Merrill <jason@redhat.com> * call.c (implicit_conversion_error): Split out from... (perform_implicit_conversion_flags): ...here. (build_converted_constant_expr_internal): Use it.
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/call.c41
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/noexcept30.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/noexcept58.C9
-rw-r--r--gcc/testsuite/g++.dg/template/crash87.C2
-rw-r--r--gcc/testsuite/g++.dg/template/nontype13.C2
6 files changed, 42 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3f135064887..f2814c3b037 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2020-05-11 Jason Merrill <jason@redhat.com>
+ * 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 <jason@redhat.com>
+
PR c++/90748
* parser.c (inject_parm_decls): Set current_class_ptr here.
(cp_parser_direct_declarator): And here.
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<typename A>
struct F {
template<typename B>
- void f() noexcept(&F::template f<B>) {} // { dg-error "exception specification|convert" }
+ void f() noexcept(&F::template f<B>) {} // { 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 ...> 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 <bool name>
class BUG2 : BUG
{
public:
- typedef BUG1_5<name> ptr; // { dg-error "convert" }
+ typedef BUG1_5<name> 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<bool B>
void tester()
{
- bar<evil>()(); // { dg-error "constant|template|convert" }
+ bar<evil>()(); // { dg-error "constant|template|convert|member function" }
}
template<bool B>
struct bar