diff mbox

[C++ Patch[ PR 66130

Message ID 555A136D.8000101@oracle.com
State New
Headers show

Commit Message

Paolo Carlini May 18, 2015, 4:29 p.m. UTC
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  <manu@gcc.gnu.org>
	    Paolo Carlini  <paolo.carlini@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  <manu@gcc.gnu.org>
	    Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/66130
	* g++.dg/other/pr66130.C: New.
	* g++.dg/cpp0x/pr66130.C: Likewise.

Comments

Paolo Carlini June 2, 2015, 6:02 p.m. UTC | #1
Hi,

gently pinging the below. Should be largely uncontroversial...

On 05/18/2015 06:29 PM, Paolo Carlini wrote:
> 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.

     https://gcc.gnu.org/ml/gcc-patches/2015-05/msg01587.html

Thanks,
Paolo.
Jason Merrill June 3, 2015, 4:31 p.m. UTC | #2
OK.

Jason
diff mbox

Patch

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;
+};