From patchwork Fri Feb 22 19:16:11 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: C++ PATCH for c++/56359 (wrong access error with function template) Date: Fri, 22 Feb 2013 09:16:11 -0000 From: Jason Merrill X-Patchwork-Id: 222678 Message-Id: <5127C3FB.1030405@redhat.com> To: gcc-patches List We need to be careful not to do any access checking on the actual arguments to the function when we're pushed into the context of the function being instantiated. Tested x86_64-pc-linux-gnu, applying to trunk. commit 7498f299d97da75ce3ab30d0626818a143fbaab9 Author: Jason Merrill Date: Fri Feb 22 10:44:03 2013 -0500 PR c++/56359 * call.c (can_convert_arg): Discard access checks. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 25dfd51..7c41421 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 0000000..e882a70 --- /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); +}