diff options
-rw-r--r-- | gcc/cp/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/cp/call.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/access25.C | 20 |
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); +} |