Commit 0ef08a81 by Jason Merrill Committed by Jason Merrill

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
parent a89b3113
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> 2013-07-06 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/28262 PR c++/28262
......
...@@ -5637,6 +5637,7 @@ extern void resume_deferring_access_checks (void); ...@@ -5637,6 +5637,7 @@ extern void resume_deferring_access_checks (void);
extern void stop_deferring_access_checks (void); extern void stop_deferring_access_checks (void);
extern void pop_deferring_access_checks (void); extern void pop_deferring_access_checks (void);
extern vec<deferred_access_check, va_gc> *get_deferred_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 void pop_to_parent_deferring_access_checks (void);
extern bool perform_access_checks (vec<deferred_access_check, va_gc> *, extern bool perform_access_checks (vec<deferred_access_check, va_gc> *,
tsubst_flags_t); tsubst_flags_t);
......
...@@ -138,6 +138,7 @@ static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*, ...@@ -138,6 +138,7 @@ static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*,
tree); tree);
static int type_unification_real (tree, tree, tree, const tree *, static int type_unification_real (tree, tree, tree, const tree *,
unsigned int, int, unification_kind_t, int, unsigned int, int, unification_kind_t, int,
vec<deferred_access_check, va_gc> **,
bool); bool);
static void note_template_header (int); static void note_template_header (int);
static tree convert_nontype_argument_function (tree, tree); static tree convert_nontype_argument_function (tree, tree);
...@@ -15052,7 +15053,6 @@ fn_type_unification (tree fn, ...@@ -15052,7 +15053,6 @@ fn_type_unification (tree fn,
return error_mark_node; return error_mark_node;
tinst = build_tree_list (fn, NULL_TREE); tinst = build_tree_list (fn, NULL_TREE);
++deduction_depth; ++deduction_depth;
push_deferring_access_checks (dk_deferred);
gcc_assert (TREE_CODE (fn) == TEMPLATE_DECL); gcc_assert (TREE_CODE (fn) == TEMPLATE_DECL);
...@@ -15144,8 +15144,13 @@ fn_type_unification (tree fn, ...@@ -15144,8 +15144,13 @@ fn_type_unification (tree fn,
} }
processing_template_decl += incomplete; processing_template_decl += incomplete;
input_location = DECL_SOURCE_LOCATION (fn); 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, fntype = tsubst (TREE_TYPE (fn), explicit_targs,
complain | tf_partial, NULL_TREE); complain | tf_partial, NULL_TREE);
pop_deferring_access_checks ();
input_location = loc; input_location = loc;
processing_template_decl -= incomplete; processing_template_decl -= incomplete;
pop_tinst_level (); pop_tinst_level ();
...@@ -15153,12 +15158,6 @@ fn_type_unification (tree fn, ...@@ -15153,12 +15158,6 @@ fn_type_unification (tree fn,
if (fntype == error_mark_node) if (fntype == error_mark_node)
goto fail; 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. */ /* Place the explicitly specified arguments in TARGS. */
for (i = NUM_TMPL_ARGS (explicit_targs); i--;) for (i = NUM_TMPL_ARGS (explicit_targs); i--;)
TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (explicit_targs, i); TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (explicit_targs, i);
...@@ -15194,9 +15193,15 @@ fn_type_unification (tree fn, ...@@ -15194,9 +15193,15 @@ fn_type_unification (tree fn,
excessive_deduction_depth = true; excessive_deduction_depth = true;
goto fail; 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), ok = !type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
targs, parms, args, nargs, /*subr=*/0, targs, parms, args, nargs, /*subr=*/0,
strict, flags, explain_p); strict, flags, &checks, explain_p);
if (!explain_p) if (!explain_p)
pop_tinst_level (); pop_tinst_level ();
if (!ok) if (!ok)
...@@ -15245,16 +15250,23 @@ fn_type_unification (tree fn, ...@@ -15245,16 +15250,23 @@ fn_type_unification (tree fn,
excessive_deduction_depth = true; excessive_deduction_depth = true;
goto fail; goto fail;
} }
/* Also collect access checks from the instantiation. */
reopen_deferring_access_checks (checks);
decl = instantiate_template (fn, targs, complain); decl = instantiate_template (fn, targs, complain);
checks = get_deferred_access_checks ();
pop_deferring_access_checks ();
pop_tinst_level (); pop_tinst_level ();
if (decl == error_mark_node) if (decl == error_mark_node)
goto fail; goto fail;
/* Now perform any access checks encountered during deduction, such as /* Now perform any access checks encountered during substitution. */
for default template arguments. */
push_access_scope (decl); push_access_scope (decl);
ok = perform_deferred_access_checks (complain); ok = perform_access_checks (checks, complain);
pop_access_scope (decl); pop_access_scope (decl);
if (!ok) if (!ok)
goto fail; goto fail;
...@@ -15283,7 +15295,6 @@ fn_type_unification (tree fn, ...@@ -15283,7 +15295,6 @@ fn_type_unification (tree fn,
r = decl; r = decl;
fail: fail:
pop_deferring_access_checks ();
--deduction_depth; --deduction_depth;
if (excessive_deduction_depth) if (excessive_deduction_depth)
{ {
...@@ -15684,7 +15695,10 @@ unify_one_argument (tree tparms, tree targs, tree parm, tree arg, ...@@ -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 If SUBR is 1, we're being called recursively (to unify the
arguments of a function or method parameter of a function 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 static int
type_unification_real (tree tparms, type_unification_real (tree tparms,
...@@ -15695,6 +15709,7 @@ type_unification_real (tree tparms, ...@@ -15695,6 +15709,7 @@ type_unification_real (tree tparms,
int subr, int subr,
unification_kind_t strict, unification_kind_t strict,
int flags, int flags,
vec<deferred_access_check, va_gc> **checks,
bool explain_p) bool explain_p)
{ {
tree parm, arg; tree parm, arg;
...@@ -15834,6 +15849,7 @@ type_unification_real (tree tparms, ...@@ -15834,6 +15849,7 @@ type_unification_real (tree tparms,
{ {
tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i)); tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
tree arg = TREE_PURPOSE (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; location_t save_loc = input_location;
if (DECL_P (parm)) if (DECL_P (parm))
input_location = DECL_SOURCE_LOCATION (parm); input_location = DECL_SOURCE_LOCATION (parm);
...@@ -15841,6 +15857,8 @@ type_unification_real (tree tparms, ...@@ -15841,6 +15857,8 @@ type_unification_real (tree tparms,
arg = convert_template_argument (parm, arg, targs, complain, arg = convert_template_argument (parm, arg, targs, complain,
i, NULL_TREE); i, NULL_TREE);
input_location = save_loc; input_location = save_loc;
*checks = get_deferred_access_checks ();
pop_deferring_access_checks ();
if (arg == error_mark_node) if (arg == error_mark_node)
return 1; return 1;
else else
...@@ -17307,7 +17325,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, ...@@ -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), return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
args, nargs, 1, DEDUCE_EXACT, args, nargs, 1, DEDUCE_EXACT,
LOOKUP_NORMAL, explain_p); LOOKUP_NORMAL, NULL, explain_p);
} }
case OFFSET_TYPE: case OFFSET_TYPE:
...@@ -20914,7 +20932,7 @@ do_auto_deduction (tree type, tree init, tree auto_node) ...@@ -20914,7 +20932,7 @@ do_auto_deduction (tree type, tree init, tree auto_node)
= build_tree_list (NULL_TREE, TYPE_NAME (auto_node)); = build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
val = type_unification_real (tparms, targs, parms, &init, 1, 0, val = type_unification_real (tparms, targs, parms, &init, 1, 0,
DEDUCE_CALL, LOOKUP_NORMAL, DEDUCE_CALL, LOOKUP_NORMAL,
/*explain_p=*/false); NULL, /*explain_p=*/false);
if (val > 0) if (val > 0)
{ {
if (processing_template_decl) if (processing_template_decl)
......
...@@ -155,6 +155,17 @@ push_deferring_access_checks (deferring_kind deferring) ...@@ -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 /* Resume deferring access checks again after we stopped doing
this previously. */ this previously. */
......
// 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>();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment