Hi,
Manuel did most of the work for this rather simple issue filed by Tom:
essentially, invalid_nonstatic_memfn_p gets a location_t parameter which
is used to pass the location of the place where the use of the nonstatic
member function is indeed invalid. Besides that, while working on the
bug we noticed that we must be careful with exprs which aren't DECLs.
Tested x86_64-linux.
Thanks,
Paolo.
////////////////////////////
2015-05-18 Manuel López-Ibáñez <m...@gcc.gnu.org>
Paolo Carlini <paolo.carl...@oracle.com>
PR c++/66130
* typeck.c (invalid_nonstatic_memfn_p): Add location_t parameter and
use it in the diagnostic.
(decay_conversion): Adjust call.
* semantics.c (finish_decltype_type): Likewise.
* call.c (resolve_args, build_new_op_1,
perform_implicit_conversion_flags): Adjust calls.
* cvt.c (ocp_convert, convert_to_void): Likewise.
* cp-tree.h (invalid_nonstatic_memfn_p): Update declaration.
2015-05-18 Manuel López-Ibáñez <m...@gcc.gnu.org>
Paolo Carlini <paolo.carl...@oracle.com>
PR c++/66130
* g++.dg/other/pr66130.C: New.
* g++.dg/cpp0x/pr66130.C: Likewise.
Index: cp/call.c
===================================================================
--- cp/call.c (revision 223295)
+++ cp/call.c (working copy)
@@ -3941,7 +3941,7 @@ resolve_args (vec<tree, va_gc> *args, tsubst_flags
error ("invalid use of void expression");
return NULL;
}
- else if (invalid_nonstatic_memfn_p (arg, complain))
+ else if (invalid_nonstatic_memfn_p (input_location, arg, complain))
return NULL;
}
return args;
@@ -5542,9 +5542,9 @@ build_new_op_1 (location_t loc, enum tree_code cod
/* If one of the arguments of the operator represents
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))
+ if (invalid_nonstatic_memfn_p (loc, arg1, tf_error)
+ || invalid_nonstatic_memfn_p (loc, arg2, tf_error)
+ || invalid_nonstatic_memfn_p (loc, arg3, tf_error))
/* We displayed the error message. */;
else
{
@@ -9409,7 +9409,7 @@ perform_implicit_conversion_flags (tree type, tree
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 (expr, complain))
+ else if (invalid_nonstatic_memfn_p (loc, expr, complain))
/* We gave an error. */;
else
error_at (loc, "could not convert %qE from %qT to %qT", expr,
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h (revision 223295)
+++ cp/cp-tree.h (working copy)
@@ -6282,7 +6282,8 @@ extern tree build_address (tree);
extern tree build_nop (tree, tree);
extern tree non_reference (tree);
extern tree lookup_anon_field (tree, tree);
-extern bool invalid_nonstatic_memfn_p (tree, tsubst_flags_t);
+extern bool invalid_nonstatic_memfn_p (location_t, tree,
+ tsubst_flags_t);
extern tree convert_member_func_to_ptr (tree, tree, tsubst_flags_t);
extern tree convert_ptrmem (tree, tree, bool, bool,
tsubst_flags_t);
Index: cp/cvt.c
===================================================================
--- cp/cvt.c (revision 223295)
+++ cp/cvt.c (working copy)
@@ -902,7 +902,7 @@ ocp_convert (tree type, tree expr, int convtype, i
{
/* 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, complain))
+ if (invalid_nonstatic_memfn_p (loc, expr, complain))
/* We displayed the error message. */;
else
error_at (loc, "conversion from %qT to non-scalar type %qT requested",
@@ -960,7 +960,7 @@ convert_to_void (tree expr, impl_conv_void implici
if (!TREE_TYPE (expr))
return expr;
- if (invalid_nonstatic_memfn_p (expr, complain))
+ if (invalid_nonstatic_memfn_p (loc, expr, complain))
return error_mark_node;
if (TREE_CODE (expr) == PSEUDO_DTOR_EXPR)
{
Index: cp/semantics.c
===================================================================
--- cp/semantics.c (revision 223295)
+++ cp/semantics.c (working copy)
@@ -7242,7 +7242,7 @@ finish_decltype_type (tree expr, bool id_expressio
expr = resolve_nondeduced_context (expr);
- if (invalid_nonstatic_memfn_p (expr, complain))
+ if (invalid_nonstatic_memfn_p (input_location, expr, complain))
return error_mark_node;
if (type_unknown_p (expr))
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (revision 223295)
+++ cp/typeck.c (working copy)
@@ -1815,7 +1815,7 @@ cxx_alignas_expr (tree e)
violates these rules. */
bool
-invalid_nonstatic_memfn_p (tree expr, tsubst_flags_t complain)
+invalid_nonstatic_memfn_p (location_t loc, tree expr, tsubst_flags_t complain)
{
if (expr == NULL_TREE)
return false;
@@ -1827,7 +1827,17 @@ bool
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (expr))
{
if (complain & tf_error)
- error ("invalid use of non-static member function");
+ {
+ if (DECL_P (expr))
+ {
+ error_at (loc, "invalid use of non-static member function %qD",
+ expr);
+ inform (DECL_SOURCE_LOCATION (expr), "declared here");
+ }
+ else
+ error_at (loc, "invalid use of non-static member function of "
+ "type %qT", TREE_TYPE (expr));
+ }
return true;
}
return false;
@@ -1951,7 +1961,7 @@ decay_conversion (tree exp, tsubst_flags_t complai
error_at (loc, "void value not ignored as it ought to be");
return error_mark_node;
}
- if (invalid_nonstatic_memfn_p (exp, complain))
+ if (invalid_nonstatic_memfn_p (loc, exp, complain))
return error_mark_node;
if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
return cp_build_addr_expr (exp, complain);
Index: testsuite/g++.dg/cpp0x/pr66130.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr66130.C (revision 0)
+++ testsuite/g++.dg/cpp0x/pr66130.C (working copy)
@@ -0,0 +1,11 @@
+// PR c++/66130
+// { dg-do compile { target c++11 } }
+
+struct Local
+{
+ void f();
+};
+
+Local *l;
+void (Local::*ptr)();
+decltype((l->*ptr)) i; // { dg-error "member function of type 'void
\\(Local::\\)\\(\\)'" }
Index: testsuite/g++.dg/other/pr66130.C
===================================================================
--- testsuite/g++.dg/other/pr66130.C (revision 0)
+++ testsuite/g++.dg/other/pr66130.C (working copy)
@@ -0,0 +1,11 @@
+// PR c++/66130
+
+struct X {
+ X(void *);
+ void m(); // { dg-message "declared here" }
+};
+
+struct Y : public X{
+ Y(void*a, void *b) : X(m), mb(b) { } // { dg-error "member function 'void
X::m\\(\\)'" }
+ void *mb;
+};