re PR c++/57550 (bogus "error ... is private")
PR c++/57550 * pt.c (fn_type_unification): Only defer during substitution. (type_unification_real): Defer during defarg substitution, add checks parm to pass back deferred checks. (unify, do_auto_deduction): Adjust. * semantics.c (reopen_deferring_access_checks): New. * cp-tree.h: Declare it. From-SVN: r200808
This commit is contained in:
parent
a89b31132d
commit
0ef08a8117
@ -1,3 +1,13 @@
|
||||
2013-07-08 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/57550
|
||||
* pt.c (fn_type_unification): Only defer during substitution.
|
||||
(type_unification_real): Defer during defarg substitution,
|
||||
add checks parm to pass back deferred checks.
|
||||
(unify, do_auto_deduction): Adjust.
|
||||
* semantics.c (reopen_deferring_access_checks): New.
|
||||
* cp-tree.h: Declare it.
|
||||
|
||||
2013-07-06 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/28262
|
||||
|
@ -5637,6 +5637,7 @@ extern void resume_deferring_access_checks (void);
|
||||
extern void stop_deferring_access_checks (void);
|
||||
extern void pop_deferring_access_checks (void);
|
||||
extern vec<deferred_access_check, va_gc> *get_deferred_access_checks (void);
|
||||
extern void reopen_deferring_access_checks (vec<deferred_access_check, va_gc> *);
|
||||
extern void pop_to_parent_deferring_access_checks (void);
|
||||
extern bool perform_access_checks (vec<deferred_access_check, va_gc> *,
|
||||
tsubst_flags_t);
|
||||
|
48
gcc/cp/pt.c
48
gcc/cp/pt.c
@ -138,6 +138,7 @@ static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*,
|
||||
tree);
|
||||
static int type_unification_real (tree, tree, tree, const tree *,
|
||||
unsigned int, int, unification_kind_t, int,
|
||||
vec<deferred_access_check, va_gc> **,
|
||||
bool);
|
||||
static void note_template_header (int);
|
||||
static tree convert_nontype_argument_function (tree, tree);
|
||||
@ -15052,7 +15053,6 @@ fn_type_unification (tree fn,
|
||||
return error_mark_node;
|
||||
tinst = build_tree_list (fn, NULL_TREE);
|
||||
++deduction_depth;
|
||||
push_deferring_access_checks (dk_deferred);
|
||||
|
||||
gcc_assert (TREE_CODE (fn) == TEMPLATE_DECL);
|
||||
|
||||
@ -15144,8 +15144,13 @@ fn_type_unification (tree fn,
|
||||
}
|
||||
processing_template_decl += incomplete;
|
||||
input_location = DECL_SOURCE_LOCATION (fn);
|
||||
/* Ignore any access checks; we'll see them again in
|
||||
instantiate_template and they might have the wrong
|
||||
access path at this point. */
|
||||
push_deferring_access_checks (dk_deferred);
|
||||
fntype = tsubst (TREE_TYPE (fn), explicit_targs,
|
||||
complain | tf_partial, NULL_TREE);
|
||||
pop_deferring_access_checks ();
|
||||
input_location = loc;
|
||||
processing_template_decl -= incomplete;
|
||||
pop_tinst_level ();
|
||||
@ -15153,12 +15158,6 @@ fn_type_unification (tree fn,
|
||||
if (fntype == error_mark_node)
|
||||
goto fail;
|
||||
|
||||
/* Throw away these access checks; we'll see them again in
|
||||
instantiate_template and they might have the wrong
|
||||
access path at this point. */
|
||||
pop_deferring_access_checks ();
|
||||
push_deferring_access_checks (dk_deferred);
|
||||
|
||||
/* Place the explicitly specified arguments in TARGS. */
|
||||
for (i = NUM_TMPL_ARGS (explicit_targs); i--;)
|
||||
TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (explicit_targs, i);
|
||||
@ -15194,9 +15193,15 @@ fn_type_unification (tree fn,
|
||||
excessive_deduction_depth = true;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* type_unification_real will pass back any access checks from default
|
||||
template argument substitution. */
|
||||
vec<deferred_access_check, va_gc> *checks;
|
||||
checks = NULL;
|
||||
|
||||
ok = !type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
|
||||
targs, parms, args, nargs, /*subr=*/0,
|
||||
strict, flags, explain_p);
|
||||
strict, flags, &checks, explain_p);
|
||||
if (!explain_p)
|
||||
pop_tinst_level ();
|
||||
if (!ok)
|
||||
@ -15245,16 +15250,23 @@ fn_type_unification (tree fn,
|
||||
excessive_deduction_depth = true;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Also collect access checks from the instantiation. */
|
||||
reopen_deferring_access_checks (checks);
|
||||
|
||||
decl = instantiate_template (fn, targs, complain);
|
||||
|
||||
checks = get_deferred_access_checks ();
|
||||
pop_deferring_access_checks ();
|
||||
|
||||
pop_tinst_level ();
|
||||
|
||||
if (decl == error_mark_node)
|
||||
goto fail;
|
||||
|
||||
/* Now perform any access checks encountered during deduction, such as
|
||||
for default template arguments. */
|
||||
/* Now perform any access checks encountered during substitution. */
|
||||
push_access_scope (decl);
|
||||
ok = perform_deferred_access_checks (complain);
|
||||
ok = perform_access_checks (checks, complain);
|
||||
pop_access_scope (decl);
|
||||
if (!ok)
|
||||
goto fail;
|
||||
@ -15283,7 +15295,6 @@ fn_type_unification (tree fn,
|
||||
r = decl;
|
||||
|
||||
fail:
|
||||
pop_deferring_access_checks ();
|
||||
--deduction_depth;
|
||||
if (excessive_deduction_depth)
|
||||
{
|
||||
@ -15684,7 +15695,10 @@ unify_one_argument (tree tparms, tree targs, tree parm, tree arg,
|
||||
|
||||
If SUBR is 1, we're being called recursively (to unify the
|
||||
arguments of a function or method parameter of a function
|
||||
template). */
|
||||
template).
|
||||
|
||||
CHECKS is a pointer to a vector of access checks encountered while
|
||||
substituting default template arguments. */
|
||||
|
||||
static int
|
||||
type_unification_real (tree tparms,
|
||||
@ -15695,6 +15709,7 @@ type_unification_real (tree tparms,
|
||||
int subr,
|
||||
unification_kind_t strict,
|
||||
int flags,
|
||||
vec<deferred_access_check, va_gc> **checks,
|
||||
bool explain_p)
|
||||
{
|
||||
tree parm, arg;
|
||||
@ -15834,6 +15849,7 @@ type_unification_real (tree tparms,
|
||||
{
|
||||
tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
|
||||
tree arg = TREE_PURPOSE (TREE_VEC_ELT (tparms, i));
|
||||
reopen_deferring_access_checks (*checks);
|
||||
location_t save_loc = input_location;
|
||||
if (DECL_P (parm))
|
||||
input_location = DECL_SOURCE_LOCATION (parm);
|
||||
@ -15841,6 +15857,8 @@ type_unification_real (tree tparms,
|
||||
arg = convert_template_argument (parm, arg, targs, complain,
|
||||
i, NULL_TREE);
|
||||
input_location = save_loc;
|
||||
*checks = get_deferred_access_checks ();
|
||||
pop_deferring_access_checks ();
|
||||
if (arg == error_mark_node)
|
||||
return 1;
|
||||
else
|
||||
@ -17307,7 +17325,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
|
||||
|
||||
return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
|
||||
args, nargs, 1, DEDUCE_EXACT,
|
||||
LOOKUP_NORMAL, explain_p);
|
||||
LOOKUP_NORMAL, NULL, explain_p);
|
||||
}
|
||||
|
||||
case OFFSET_TYPE:
|
||||
@ -20914,7 +20932,7 @@ do_auto_deduction (tree type, tree init, tree auto_node)
|
||||
= build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
|
||||
val = type_unification_real (tparms, targs, parms, &init, 1, 0,
|
||||
DEDUCE_CALL, LOOKUP_NORMAL,
|
||||
/*explain_p=*/false);
|
||||
NULL, /*explain_p=*/false);
|
||||
if (val > 0)
|
||||
{
|
||||
if (processing_template_decl)
|
||||
|
@ -155,6 +155,17 @@ push_deferring_access_checks (deferring_kind deferring)
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the current deferred access states and start deferred access
|
||||
checking, continuing the set of deferred checks in CHECKS. */
|
||||
|
||||
void
|
||||
reopen_deferring_access_checks (vec<deferred_access_check, va_gc> * checks)
|
||||
{
|
||||
push_deferring_access_checks (dk_deferred);
|
||||
if (!deferred_access_no_check)
|
||||
deferred_access_stack->last().deferred_access_checks = checks;
|
||||
}
|
||||
|
||||
/* Resume deferring access checks again after we stopped doing
|
||||
this previously. */
|
||||
|
||||
|
17
gcc/testsuite/g++.dg/template/access27.C
Normal file
17
gcc/testsuite/g++.dg/template/access27.C
Normal file
@ -0,0 +1,17 @@
|
||||
// PR c++/57550
|
||||
|
||||
template <bool (double)> bool Wrapper(double);
|
||||
template <class T> void MakeHandler(bool (T));
|
||||
|
||||
class Handler
|
||||
{
|
||||
public:
|
||||
template <typename T> static void SetPrimitiveHandlers()
|
||||
{
|
||||
MakeHandler(Wrapper<Append<T> >);
|
||||
}
|
||||
private :
|
||||
template <typename T> static bool Append(T);
|
||||
};
|
||||
|
||||
template void Handler::SetPrimitiveHandlers<double>();
|
Loading…
Reference in New Issue
Block a user