Hi,

On 08/01/2012 04:32 PM, Jason Merrill wrote:
I think the problem is that we're deferring access control due to
tentative parsing on line 11, and not on line 13.  I guess we need a

push_deferring_access_checks (dk_no_deferred);
pop_deferring_access_checks ();

around the substitution of default template args in
type_unification_real.
Great, thanks. Thus, I have been testing the attached and it definitely works for the testcases I discussed so far. Testsuite seems also Ok (lightly tested so far).

However, something weird is going on for this variant, using decltype (wanted to consistently extend sfinae37.C):

class C {
   typedef int type;
};

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

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

static_assert(sizeof(g<C>(0)) == 2, "Ouch");          // line 11

typedef int testg[sizeof(g<C>(0)) == 2 ? 1 : -1];      // line 13

what happens is that line 13 is mishandled:

sfinae37_red.C:13:48: error: size of array ‘testg’ is negative

However, *if I comment out line 11*, things work for line 13! If I swap line 11 and line 13 then the declaration of testg is accepted and the static_assert triggers. In any case, only the first evaluation of the sizeof is correct, the next are incorrect. The issue seems so weird that it should be easy to fix... ;)

Final important observation: in fact, this variant with decltype is handled in the same way with or without the push_deferring_access_checks / pop_deferring_access_checks calls.

Paolo.

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

Index: pt.c
===================================================================
--- pt.c        (revision 190031)
+++ pt.c        (working copy)
@@ -15122,9 +15122,11 @@ type_unification_real (tree tparms,
              location_t save_loc = input_location;
              if (DECL_P (parm))
                input_location = DECL_SOURCE_LOCATION (parm);
+             push_deferring_access_checks (dk_no_deferred);
              arg = tsubst_template_arg (arg, targs, complain, NULL_TREE);
              arg = convert_template_argument (parm, arg, targs, complain,
                                               i, NULL_TREE);
+             pop_deferring_access_checks ();
              input_location = save_loc;
              if (arg == error_mark_node)
                return 1;

Reply via email to