summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/call.c7
-rw-r--r--gcc/testsuite/g++.dg/template/access25.C20
3 files changed, 30 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8f0872b13fc..6b3aa17edc2 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 25dfd51c4f9..7c414217f05 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 00000000000..e882a7099d9
--- /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);
+}