Commit 248e1b22 by Mark Mitchell Committed by Mark Mitchell

re PR c++/37971 (Rejects default argument that is a template via access failure)

	PR c++/37971
	* class.c (resolve_address_of_overloaded_function): Check
	accessibility of member functions unless FLAGS indicates
	otherwise.
	* call.c (standard_conversion): Adjust flags passed to
	instantiate_type.
	(convert_default_arg): Do not perform access checks.
	* cp-tree.h (tsubst_flags_t): Add tf_no_access_control.

	PR c++/37971
	* g++.dg/overload/defarg2.C: New test.
	* g++.dg/overload/defarg3.C: Likewise.

From-SVN: r142628
parent 3725c2e3
2008-12-09 Mark Mitchell <mark@codesourcery.com>
PR c++/37971
* class.c (resolve_address_of_overloaded_function): Check
accessibility of member functions unless FLAGS indicates
otherwise.
* call.c (standard_conversion): Adjust flags passed to
instantiate_type.
(convert_default_arg): Do not perform access checks.
* cp-tree.h (tsubst_flags_t): Add tf_no_access_control.
2008-12-08 Steve Ellcey <sje@cup.hp.com>
* decl2.c (mark_used): Remove assemble_external call.
......
......@@ -706,7 +706,10 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to))
&& expr && type_unknown_p (expr))
{
expr = instantiate_type (to, expr, tf_conv);
tsubst_flags_t tflags = tf_conv;
if (!(flags & LOOKUP_PROTECT))
tflags |= tf_no_access_control;
expr = instantiate_type (to, expr, tflags);
if (expr == error_mark_node)
return NULL;
from = TREE_TYPE (expr);
......@@ -1360,9 +1363,8 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags)
/* Returns the implicit conversion sequence (see [over.ics]) from type
FROM to type TO. The optional expression EXPR may affect the
conversion. FLAGS are the usual overloading flags. Only
LOOKUP_NO_CONVERSION is significant. If C_CAST_P is true, this
conversion is coming from a C-style cast. */
conversion. FLAGS are the usual overloading flags. If C_CAST_P is
true, this conversion is coming from a C-style cast. */
static conversion *
implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
......@@ -4954,8 +4956,17 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
if (fn && DECL_TEMPLATE_INFO (fn))
arg = tsubst_default_argument (fn, type, arg);
arg = break_out_target_exprs (arg);
/* Due to:
[dcl.fct.default]
The names in the expression are bound, and the semantic
constraints are checked, at the point where the default
expressions appears.
we must not perform access checks here. */
push_deferring_access_checks (dk_no_check);
arg = break_out_target_exprs (arg);
if (TREE_CODE (arg) == CONSTRUCTOR)
{
arg = digest_init (type, arg);
......@@ -4978,6 +4989,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
tf_warning_or_error);
arg = convert_for_arg_passing (type, arg);
}
pop_deferring_access_checks();
VEC_pop (tree, default_arg_context);
......
......@@ -5923,9 +5923,13 @@ pop_lang_context (void)
control of FLAGS. Permit pointers to member function if FLAGS
permits. If TEMPLATE_ONLY, the name of the overloaded function was
a template-id, and EXPLICIT_TARGS are the explicitly provided
template arguments. If OVERLOAD is for one or more member
functions, then ACCESS_PATH is the base path used to reference
those member functions. */
template arguments.
If OVERLOAD is for one or more member functions, then ACCESS_PATH
is the base path used to reference those member functions. If
TF_NO_ACCESS_CONTROL is not set in FLAGS, and the address is
resolved to a member function, access checks will be performed and
errors issued if appropriate. */
static tree
resolve_address_of_overloaded_function (tree target_type,
......@@ -6190,14 +6194,16 @@ resolve_address_of_overloaded_function (tree target_type,
return error_mark_node;
mark_used (fn);
/* We could not check access when this expression was originally
created since we did not know at that time to which function
the expression referred. */
if (DECL_FUNCTION_MEMBER_P (fn))
{
gcc_assert (access_path);
perform_or_defer_access_check (access_path, fn, fn);
}
}
/* We could not check access to member functions when this
expression was originally created since we did not know at that
time to which function the expression referred. */
if (!(flags & tf_no_access_control)
&& DECL_FUNCTION_MEMBER_P (fn))
{
gcc_assert (access_path);
perform_or_defer_access_check (access_path, fn, fn);
}
if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
......
......@@ -3560,20 +3560,22 @@ typedef enum linkage_kind {
/* Bitmask flags to control type substitution. */
typedef enum tsubst_flags_t {
tf_none = 0, /* nothing special */
tf_error = 1 << 0, /* give error messages */
tf_warning = 1 << 1, /* give warnings too */
tf_ignore_bad_quals = 1 << 2, /* ignore bad cvr qualifiers */
tf_keep_type_decl = 1 << 3, /* retain typedef type decls
(make_typename_type use) */
tf_ptrmem_ok = 1 << 4, /* pointers to member ok (internal
instantiate_type use) */
tf_user = 1 << 5, /* found template must be a user template
(lookup_template_class use) */
tf_conv = 1 << 6, /* We are determining what kind of
conversion might be permissible,
not actually performing the
conversion. */
tf_none = 0, /* nothing special */
tf_error = 1 << 0, /* give error messages */
tf_warning = 1 << 1, /* give warnings too */
tf_ignore_bad_quals = 1 << 2, /* ignore bad cvr qualifiers */
tf_keep_type_decl = 1 << 3, /* retain typedef type decls
(make_typename_type use) */
tf_ptrmem_ok = 1 << 4, /* pointers to member ok (internal
instantiate_type use) */
tf_user = 1 << 5, /* found template must be a user template
(lookup_template_class use) */
tf_conv = 1 << 6, /* We are determining what kind of
conversion might be permissible,
not actually performing the
conversion. */
tf_no_access_control = 1 << 7, /* Do not perform access checks, even
when issuing other errors. */
/* Convenient substitution flags combinations. */
tf_warning_or_error = tf_warning | tf_error
} tsubst_flags_t;
......
2008-12-09 Mark Mitchell <mark@codesourcery.com>
PR c++/37971
* g++.dg/overload/defarg2.C: New test.
* g++.dg/overload/defarg3.C: Likewise.
2008-12-09 Jakub Jelinek <jakub@redhat.com>
PR middle-end/38454
......
// PR c++/37391
// { dg-do compile }
class C {
private:
static int f(int);
static int f(char);
public:
static void g(int (*)(int) = f);
};
void h() {
/* Although C::f is inaccessible here, it is accessible in the
context of C::g, so there is no error. */
C::g();
}
// PR c++/37391
// { dg-do compile }
class C {
private:
static int f(int); // { dg-error "private" }
static int f(char);
};
class D {
public:
/* C::f is inaccessible, so this is an error, even if this function
is never called. */
static void g(int (*)(int) = C::f); // { dg-error "context" }
};
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