Commit 111a28c2 by Dodji Seketeli

re PR c++/38228 (ICE with invalid use of bound member function)

    gcc/cp/ChangeLog:
    	PR c++/38228
    	* pt.c (unify): Do not allow the result of a template argument
    	deduction to be a METHOD_TYPE.
    	* cvt.c (cp_convert): Report a meaningful error for non-valid use
    	of pointer to member functions during conversions.
    	* call.c (build_new_op): Report a meaningful error for non-valid
    	use of pointer to member functions in binary expressions.
    	* typeck.c (invalid_nonstatic_memfn_p): Do not crash when EXPR is
    	NULL;
    
    gcc/testsuite/ChangeLog:
    	PR c++/38228
    	* g++.dg/expr/bound-mem-fun.C: New test.

From-SVN: r146646
parent c1abd261
...@@ -4072,8 +4072,20 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, ...@@ -4072,8 +4072,20 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
default: default:
if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error)) if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
{ {
op_error (code, code2, arg1, arg2, arg3, "no match"); /* If one of the arguments of the operator represents
print_z_candidates (candidates); an invalid use of member function pointer, try to report
a meaningful error ... */
if (invalid_nonstatic_memfn_p (arg1, tf_error)
|| invalid_nonstatic_memfn_p (arg2, tf_error)
|| invalid_nonstatic_memfn_p (arg3, tf_error))
/* We displayed the error message. */;
else
{
/* ... Otherwise, report the more generic
"no matching operator found" error */
op_error (code, code2, arg1, arg2, arg3, "no match");
print_z_candidates (candidates);
}
} }
result = error_mark_node; result = error_mark_node;
break; break;
......
...@@ -760,8 +760,15 @@ ocp_convert (tree type, tree expr, int convtype, int flags) ...@@ -760,8 +760,15 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
} }
if (flags & LOOKUP_COMPLAIN) if (flags & LOOKUP_COMPLAIN)
error ("conversion from %qT to non-scalar type %qT requested", {
TREE_TYPE (expr), type); /* If the conversion failed and expr was an invalid use of pointer to
member function, try to report a meaningful error. */
if (invalid_nonstatic_memfn_p (expr, tf_warning_or_error))
/* We displayed the error message. */;
else
error ("conversion from %qT to non-scalar type %qT requested",
TREE_TYPE (expr), type);
}
return error_mark_node; return error_mark_node;
} }
......
...@@ -13581,6 +13581,13 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict) ...@@ -13581,6 +13581,13 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
&& !template_parameter_pack_p (parm)) && !template_parameter_pack_p (parm))
return 1; return 1;
/* If the argument deduction results is a METHOD_TYPE,
then there is a problem.
METHOD_TYPE doesn't map to any real C++ type the result of
the deduction can not be of that type. */
if (TREE_CODE (arg) == METHOD_TYPE)
return 1;
TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg; TREE_VEC_ELT (INNERMOST_TEMPLATE_ARGS (targs), idx) = arg;
return 0; return 0;
......
...@@ -1508,7 +1508,7 @@ cxx_sizeof_or_alignof_expr (tree e, enum tree_code op, bool complain) ...@@ -1508,7 +1508,7 @@ cxx_sizeof_or_alignof_expr (tree e, enum tree_code op, bool complain)
bool bool
invalid_nonstatic_memfn_p (const_tree expr, tsubst_flags_t complain) invalid_nonstatic_memfn_p (const_tree expr, tsubst_flags_t complain)
{ {
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (expr)) if (expr && DECL_NONSTATIC_MEMBER_FUNCTION_P (expr))
{ {
if (complain & tf_error) if (complain & tf_error)
error ("invalid use of non-static member function"); error ("invalid use of non-static member function");
......
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR c++/38228
// { dg-do "compile" }
struct A
{
A ();
template<typename T> A(T);
};
struct B
{
int foo();
};
A a = B().*(&B::foo); // { dg-error "invalid use of non-static member function" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment