From 3ced2284b437b9e5a46c165df006a5a52cb5d18c Mon Sep 17 00:00:00 2001
From: Jason Merrill <jason@redhat.com>
Date: Fri, 22 Feb 2013 17:24:10 -0500
Subject: [PATCH] re PR c++/56359 (Bogus "error: no matching function for call
 to ...")

	PR c++/56359
	* call.c (can_convert_arg): Discard access checks.

From-SVN: r196229
---
 gcc/cp/ChangeLog                         |  3 +++
 gcc/cp/call.c                            |  7 +++++++
 gcc/testsuite/g++.dg/template/access25.C | 20 ++++++++++++++++++++
 3 files changed, 30 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/template/access25.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8f0872b13fcb..6b3aa17edc2a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,8 @@
 2013-02-22  Jason Merrill  <jason@redhat.com>
 
+	PR c++/56359
+	* call.c (can_convert_arg): Discard access checks.
+
 	PR c++/56395
 	* tree.c (strip_typedefs): Strip typedefs from TYPENAME_TYPE template
 	args.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 25dfd51c4f96..7c414217f05f 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -8765,11 +8765,18 @@ can_convert_arg (tree to, tree from, tree arg, int flags,
 
   /* Get the high-water mark for the CONVERSION_OBSTACK.  */
   p = conversion_obstack_alloc (0);
+  /* We want to discard any access checks done for this test,
+     as we might not be in the appropriate access context and
+     we'll do the check again when we actually perform the
+     conversion.  */
+  push_deferring_access_checks (dk_deferred);
 
   t  = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
 			    flags, complain);
   ok_p = (t && !t->bad_p);
 
+  /* Discard the access checks now.  */
+  pop_deferring_access_checks ();
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
 
diff --git a/gcc/testsuite/g++.dg/template/access25.C b/gcc/testsuite/g++.dg/template/access25.C
new file mode 100644
index 000000000000..e882a7099d98
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/access25.C
@@ -0,0 +1,20 @@
+// PR c++/56359
+
+typedef int (*InvocationCallback) (const int &);
+
+template < typename target_t >
+void SetPrototypeMethod (target_t, const char *, InvocationCallback);
+
+class A
+{
+    void Initialize ();
+protected:
+    static int Stop (const int &);
+    void Stop ();  // comment out to make the bug disappear.
+};
+
+void
+A::Initialize ()
+{
+    SetPrototypeMethod (0, "stop", A::Stop);
+}
-- 
GitLab