This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC / RFH] Re-opened C++/51213 (access control under SFINAE)


Hi,

thus I started analyzing why we are handling incorrectly some variants posted by Daniel. A typical example (another is about using the sizeof in a template argument) is:

class C {
typedef int type; // Line 2
};

template<class T, class = typename T::type>
auto f(int) -> char;

template<class>
auto f(...) -> char (&)[2];

typedef int test[sizeof(f<C>(0)) == 2 ? 1 : -1]; // Error (line #11)

// static_assert(sizeof(f<C>(0)) == 2, ""); // OK (line #13)

the first interesting bit of analysis I can offer is a comparison vs 4.7. This is the error message with 4.7:

51213_3.C:11:47: error: size of array ‘test’ is negative

as you can see, nothing about access control! Thus, it seems to me, the issues we are having with mainline ultimately boil down to non-conforming/missing access control in pre-existing code. In current mainline, for comparison, we have:

51213_3.C:11:47: error: size of array ‘test’ is negative
typedef int test[sizeof(f<C>(0)) == 2 ? 1 : -1]; // Error (line #11)
^
51213_3.C:2:15: error: ‘typedef int C::type’ is private
typedef int type; // Line 2
^
51213_3.C:5:19: error: within this context
template<class T, class = typename T::type>

thus, what is happening is that we actually do access control, but too late, with the SFINAE already mishandled. Thus, it seems that, irrespective of the access control under SFINAE bits, we are making progress here, we actually do access control now, only, too late, because it should happen earlier, and fail in time for SFINAE.

In little more detail, in mainline we reach perform_or_defer_access_check from perform_overload_resolution, but ptr->deferring_access_checks_kind == dk_deferred, thus the former has no chances to call enforce_access and return false. I'm adding below the stacktrace. On the other hand, in the case which already works (commented out above), ptr->deferring_access_checks_kind == dk_no_deferred and everything is fine.

So, it looks like we are deferring an access check which shouldn't be deferred, at least should happen in time for SFINAE. At the moment, I have no idea why it is happening only for line #11 and not for line #13.

Jason, are those first bits of analysis enough for you to figure out what could be possibly going wrong? Or you have suggestions about the next steps? If on the other hand, you feel like just taking over from here (eg, the issue seems interesting enough ;) just let me know...

Thanks!
Paolo.

/////////////////////////////////

Breakpoint 2, perform_or_defer_access_check (binfo=0x7ffff6e664e0, decl=0x7ffff6e59ac8, diag_decl=0x7ffff6e59ac8, complain=8) at /scratch/Gcc/svn-dirs/trunk/gcc/cp/semantics.c:327
(gdb) bt
#0 perform_or_defer_access_check (binfo=0x7ffff6e664e0, decl=0x7ffff6e59ac8, diag_decl=0x7ffff6e59ac8, complain=8) at /scratch/Gcc/svn-dirs/trunk/gcc/cp/semantics.c:327
#1 0x000000000051f8bb in make_typename_type (context=0x7ffff6e5e888, name=0x7ffff6e6c8f0, tag_type=typename_type, complain=8) at /scratch/Gcc/svn-dirs/trunk/gcc/cp/decl.c:3311
#2 0x00000000005e8c6f in tsubst (t=0x7ffff6e5ebd0, args=0x7ffff6d16b10, complain=0, in_decl=0x0) at /scratch/Gcc/svn-dirs/trunk/gcc/cp/pt.c:11405
#3 0x00000000005ce538 in tsubst_template_arg (t=0x7ffff6e5ebd0, args=0x7ffff6d16b10, complain=0, in_decl=0x0) at /scratch/Gcc/svn-dirs/trunk/gcc/cp/pt.c:8917
#4 0x000000000060d472 in type_unification_real (tparms=0x7ffff6d16900, targs=0x7ffff6d16b10, xparms=0x7ffff6e6d370, xargs=0x7fffffffc060, xnargs=1, subr=0, strict=DEDUCE_CALL, flags=1, explain_p=0 '\000') at /scratch/Gcc/svn-dirs/trunk/gcc/cp/pt.c:15125
#5 0x000000000060af3f in fn_type_unification (fn=0x7ffff6e59e60, explicit_targs=0x7ffff6e6d500, targs=0x7ffff6d16b10, args=0x7fffffffc060, nargs=1, return_type=0x0, strict=DEDUCE_CALL, flags=1, explain_p=0 '\000') at /scratch/Gcc/svn-dirs/trunk/gcc/cp/pt.c:14648
#6 0x00000000004de20a in add_template_candidate_real (candidates=0x7fffffffc590, tmpl=0x7ffff6e59e60, ctype=0x0, explicit_targs=0x7ffff6e6d500, first_arg=0x0, arglist=0x7ffff6e6d528, return_type=0x0, access_path=0x0, conversion_path=0x0, flags=1, obj=0x0, strict=DEDUCE_CALL, complain=3) at /scratch/Gcc/svn-dirs/trunk/gcc/cp/call.c:2921
#7 0x00000000004deb48 in add_template_candidate (candidates=0x7fffffffc590, tmpl=0x7ffff6e59e60, ctype=0x0, explicit_targs=0x7ffff6e6d500, first_arg=0x0, arglist=0x7ffff6e6d528, return_type=0x0, access_path=0x0, conversion_path=0x0, flags=1, strict=DEDUCE_CALL, complain=3) at /scratch/Gcc/svn-dirs/trunk/gcc/cp/call.c:3024
#8 0x00000000004e8375 in add_candidates (fns=0x7ffff6e6a640, first_arg=0x0, args=0x7ffff6e6d528, return_type=0x0, explicit_targs=0x7ffff6e6d500, template_only=1 '\001', conversion_path=0x0, access_path=0x0, flags=1, candidates=0x7fffffffc590, complain=3) at /scratch/Gcc/svn-dirs/trunk/gcc/cp/call.c:4939
#9 0x00000000004e2702 in perform_overload_resolution (fn=0x7ffff6e6a6c0, args=0x7ffff6e6d528, candidates=0x7fffffffc590, any_viable_p=0x7fffffffc58f "\001 \201\201\001", complain=3) at /scratch/Gcc/svn-dirs/trunk/gcc/cp/call.c:3823



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]