Patchwork C++ PATCH for c++/52597 (misleading diagnostic for wrong use of member function)

login
register
mail settings
Submitter Jason Merrill
Date March 27, 2013, 2:56 a.m.
Message ID <51525FF5.5070504@redhat.com>
Download mbox | patch
Permalink /patch/231584/
State New
Headers show

Comments

Jason Merrill - March 27, 2013, 2:56 a.m.
When we see a use of a non-overloaded non-static member function, we 
give the resulting expression unknown type so that invalid uses get 
errors.  But the "can't resolve overloading" error is wrong in this 
case, so we should give the right one.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit fa430ccf08f60e0affd935854fd8b49f547d21a4
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Mar 26 14:26:29 2013 -0400

    	PR c++/52597
    	* typeck.c (invalid_nonstatic_memfn_p): Use get_first_fn.  Take tree.
    	* semantics.c (finish_decltype_type): Check it before type_unknown_p.
    	* cp-tree.h: Adjust prototype.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4018685..36671d5 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5988,7 +5988,7 @@  extern tree build_typed_address			(tree, 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		(const_tree, tsubst_flags_t);
+extern bool invalid_nonstatic_memfn_p		(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);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 127e2da..8cf7886 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5276,16 +5276,16 @@  finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
 
   expr = resolve_nondeduced_context (expr);
 
-  if (type_unknown_p (expr))
-    {
-      if (complain & tf_error)
-	error ("decltype cannot resolve address of overloaded function");
-      return error_mark_node;
-    }
-
   if (invalid_nonstatic_memfn_p (expr, complain))
     return error_mark_node;
 
+  if (type_unknown_p (expr))
+    {
+      if (complain & tf_error)
+	error ("decltype cannot resolve address of overloaded function");
+      return error_mark_node;
+    }
+
   /* To get the size of a static data member declared as an array of
      unknown bound, we need to instantiate it.  */
   if (TREE_CODE (expr) == VAR_DECL
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 4e42a9d..8778b2c 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -1766,9 +1766,16 @@  cxx_alignas_expr (tree e)
    violates these rules.  */
 
 bool
-invalid_nonstatic_memfn_p (const_tree expr, tsubst_flags_t complain)
+invalid_nonstatic_memfn_p (tree expr, tsubst_flags_t complain)
 {
-  if (expr && DECL_NONSTATIC_MEMBER_FUNCTION_P (expr))
+  if (expr == NULL_TREE)
+    return false;
+  /* Don't enforce this in MS mode.  */
+  if (flag_ms_extensions)
+    return false;
+  if (is_overloaded_fn (expr) && !really_overloaded_fn (expr))
+    expr = get_first_fn (expr);
+  if (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/cpp0x/decltype50.C b/gcc/testsuite/g++.dg/cpp0x/decltype50.C
new file mode 100644
index 0000000..dc3332a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype50.C
@@ -0,0 +1,18 @@ 
+// PR c++/52597
+// { dg-require-effective-target c++11 }
+
+struct A {
+   int zip();
+
+   decltype(zip) bar0; // { dg-error "invalid use of non-static member function" }
+   void bar1() {
+     typedef decltype(this->A::zip) x; // { dg-error "invalid use of non-static member function" }
+   }
+   void bar2() {
+     typedef decltype(A::zip) x; // { dg-error "invalid use of non-static member function" }
+   }
+};
+
+typedef decltype(A().zip) x; // { dg-error "invalid use of non-static member function" }
+
+// { dg-prune-output "invalid type in declaration" }
diff --git a/gcc/testsuite/g++.dg/template/overload6.C b/gcc/testsuite/g++.dg/template/overload6.C
index 5e26c44..8d574e7 100644
--- a/gcc/testsuite/g++.dg/template/overload6.C
+++ b/gcc/testsuite/g++.dg/template/overload6.C
@@ -4,7 +4,7 @@ 
 // PR 21592:ICE
 // Origin:  Volker Reichelt <reichelt@gcc.gnu.org>
 
-template<typename T> void unique(T,T); // { dg-message "note" }
+template<typename T> void unique(T,T);
 
 struct A
 {
@@ -13,6 +13,5 @@  struct A
 
 template<int> void foo()
 {
-  unique(A().begin); // { dg-error "no matching function" "" }
-  // { dg-message "candidate" "candidate note" { target *-*-* } 16 }
+  unique(A().begin); // { dg-error "invalid use of non-static member function" }
 }
diff --git a/gcc/testsuite/g++.dg/template/ptrmem4.C b/gcc/testsuite/g++.dg/template/ptrmem4.C
index 14f36d4..0765032 100644
--- a/gcc/testsuite/g++.dg/template/ptrmem4.C
+++ b/gcc/testsuite/g++.dg/template/ptrmem4.C
@@ -6,7 +6,7 @@ 
 // Pointer to member function template argument deduction ICE.
 
 
-template <class CONT> void queryAliases(CONT& fill_me); // { dg-message "queryAliases|no known conversion" }
+template <class CONT> void queryAliases(CONT& fill_me);
 
 struct SpyExample
 {
@@ -16,5 +16,5 @@  struct SpyExample
 
 void SpyExample::ready()
 {
-  queryAliases(inputs); // { dg-error "matching|unresolved" }
+  queryAliases(inputs); // { dg-error "invalid" }
 }
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p11110.C b/gcc/testsuite/g++.old-deja/g++.mike/p11110.C
index 7e3a1ff..714f628 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p11110.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p11110.C
@@ -6,7 +6,7 @@  class data;
 class conatiner {
 public:
   virtual void* first    ();
-  virtual data* contents (void* i);     // { dg-message "conatiner::contents|no known conversion" }
+  virtual data* contents (void* i);
 };
 
 class user {
@@ -17,6 +17,5 @@  private:
 };
 
 data* user::data1() const {
-  return (_c.contents (_c.first));	// { dg-error "match" } 
-  // { dg-message "candidate" "candidate note" { target *-*-* } 20 }
+  return (_c.contents (_c.first)); // { dg-error "invalid use of non-static member function" }
 }