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.
This commit is contained in:
parent
f981395c22
commit
42e9f80bf4
@ -1,3 +1,9 @@
|
||||
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
|
||||
|
@ -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)
|
||||
|
@ -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 () {
|
||||
|
9
gcc/testsuite/g++.dg/cpp0x/noexcept58.C
Normal file
9
gcc/testsuite/g++.dg/cpp0x/noexcept58.C
Normal file
@ -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;
|
@ -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()
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user