This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA] PATCH for PR c++/38228


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Jason Merrill a écrit :
> The new errors should be controlled by LOOKUP_COMPLAIN just like the old
> errors.  You aren't adding a new situation where we give errors, just
> changing which error message we give.

OK.

The attached patch should fix that.

Thanks.

D.



-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Remi - http://enigmail.mozdev.org

iEYEARECAAYFAknt+7cACgkQPejI7lrem2HHeACgi9S64IeKHCH3Ab7GxzcP+Xq2
YU8An2Ui2qQC9uma7S/UAjBWV8aMyOqA
=1btJ
-----END PGP SIGNATURE-----
commit 9a25f8bc62557dc9f88a2dd64da989298ab7d328
Author: Dodji Seketeli <dodji@redhat.com>
Date:   Tue Apr 14 15:28:13 2009 +0200

    Fix candidate for PR38228
    
    gcc/cp/ChangeLog:
    2009-04-14  Dodji Seketeli  <dodji@redhat.com>
    	PR c++/38228
    	* pt.c (unify): Do not allow the result of a template argument
    	deduction to be a METHOD_TYPE.
    	* ocvt.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:
    2009-04-14  Dodji Seketeli  <dodji@redhat.com>
    	PR c++/38228
    	* g++.dg/expr/bound-mem-fun.C: New test.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index c942712..40371bf 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4069,8 +4069,20 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
 	default:
 	  if ((flags & LOOKUP_COMPLAIN) && (complain & tf_error))
 	    {
-	      op_error (code, code2, arg1, arg2, arg3, "no match");
-	      print_z_candidates (candidates);
+		/* 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))
+		  /* 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;
 	  break;
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index fed4ab2..7ad456b 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -759,9 +759,16 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
 	return build_cplus_new (type, ctor);
     }
 
+  /* If the conversion failed and expr was an invalid use of pointer to
+     member function, try to report a meaningful error.  */
   if (flags & LOOKUP_COMPLAIN)
-    error ("conversion from %qT to non-scalar type %qT requested",
-	   TREE_TYPE (expr), type);
+    {
+      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;
 }
 
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8dd3579..a5b8b63 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -13578,6 +13578,13 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict)
 	  && !template_parameter_pack_p (parm))
 	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;
       return 0;
 
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index fe791f3..1152c80 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1508,7 +1508,7 @@ cxx_sizeof_or_alignof_expr (tree e, enum tree_code op, bool complain)
 bool
 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)
         error ("invalid use of non-static member function");
diff --git a/gcc/testsuite/g++.dg/expr/bound-mem-fun.C b/gcc/testsuite/g++.dg/expr/bound-mem-fun.C
new file mode 100644
index 0000000..9e699b6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/bound-mem-fun.C
@@ -0,0 +1,18 @@
+// 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" }
+
+

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]