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> 2008-12-08 Steve Ellcey <sje@cup.hp.com>
* decl2.c (mark_used): Remove assemble_external call. * decl2.c (mark_used): Remove assemble_external call.
......
...@@ -706,7 +706,10 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p, ...@@ -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)) if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to))
&& expr && type_unknown_p (expr)) && 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) if (expr == error_mark_node)
return NULL; return NULL;
from = TREE_TYPE (expr); from = TREE_TYPE (expr);
...@@ -1360,9 +1363,8 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags) ...@@ -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 /* Returns the implicit conversion sequence (see [over.ics]) from type
FROM to type TO. The optional expression EXPR may affect the FROM to type TO. The optional expression EXPR may affect the
conversion. FLAGS are the usual overloading flags. Only conversion. FLAGS are the usual overloading flags. If C_CAST_P is
LOOKUP_NO_CONVERSION is significant. If C_CAST_P is true, this true, this conversion is coming from a C-style cast. */
conversion is coming from a C-style cast. */
static conversion * static conversion *
implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, 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) ...@@ -4954,8 +4956,17 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
if (fn && DECL_TEMPLATE_INFO (fn)) if (fn && DECL_TEMPLATE_INFO (fn))
arg = tsubst_default_argument (fn, type, arg); 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) if (TREE_CODE (arg) == CONSTRUCTOR)
{ {
arg = digest_init (type, arg); arg = digest_init (type, arg);
...@@ -4978,6 +4989,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum) ...@@ -4978,6 +4989,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
tf_warning_or_error); tf_warning_or_error);
arg = convert_for_arg_passing (type, arg); arg = convert_for_arg_passing (type, arg);
} }
pop_deferring_access_checks();
VEC_pop (tree, default_arg_context); VEC_pop (tree, default_arg_context);
......
...@@ -5923,9 +5923,13 @@ pop_lang_context (void) ...@@ -5923,9 +5923,13 @@ pop_lang_context (void)
control of FLAGS. Permit pointers to member function if FLAGS control of FLAGS. Permit pointers to member function if FLAGS
permits. If TEMPLATE_ONLY, the name of the overloaded function was permits. If TEMPLATE_ONLY, the name of the overloaded function was
a template-id, and EXPLICIT_TARGS are the explicitly provided a template-id, and EXPLICIT_TARGS are the explicitly provided
template arguments. If OVERLOAD is for one or more member template arguments.
functions, then ACCESS_PATH is the base path used to reference
those member functions. */ 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 static tree
resolve_address_of_overloaded_function (tree target_type, resolve_address_of_overloaded_function (tree target_type,
...@@ -6190,14 +6194,16 @@ resolve_address_of_overloaded_function (tree target_type, ...@@ -6190,14 +6194,16 @@ resolve_address_of_overloaded_function (tree target_type,
return error_mark_node; return error_mark_node;
mark_used (fn); 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. */ /* We could not check access to member functions when this
if (DECL_FUNCTION_MEMBER_P (fn)) expression was originally created since we did not know at that
{ time to which function the expression referred. */
gcc_assert (access_path); if (!(flags & tf_no_access_control)
perform_or_defer_access_check (access_path, fn, fn); && 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)) if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type))
......
...@@ -3560,20 +3560,22 @@ typedef enum linkage_kind { ...@@ -3560,20 +3560,22 @@ typedef enum linkage_kind {
/* Bitmask flags to control type substitution. */ /* Bitmask flags to control type substitution. */
typedef enum tsubst_flags_t { typedef enum tsubst_flags_t {
tf_none = 0, /* nothing special */ tf_none = 0, /* nothing special */
tf_error = 1 << 0, /* give error messages */ tf_error = 1 << 0, /* give error messages */
tf_warning = 1 << 1, /* give warnings too */ tf_warning = 1 << 1, /* give warnings too */
tf_ignore_bad_quals = 1 << 2, /* ignore bad cvr qualifiers */ tf_ignore_bad_quals = 1 << 2, /* ignore bad cvr qualifiers */
tf_keep_type_decl = 1 << 3, /* retain typedef type decls tf_keep_type_decl = 1 << 3, /* retain typedef type decls
(make_typename_type use) */ (make_typename_type use) */
tf_ptrmem_ok = 1 << 4, /* pointers to member ok (internal tf_ptrmem_ok = 1 << 4, /* pointers to member ok (internal
instantiate_type use) */ instantiate_type use) */
tf_user = 1 << 5, /* found template must be a user template tf_user = 1 << 5, /* found template must be a user template
(lookup_template_class use) */ (lookup_template_class use) */
tf_conv = 1 << 6, /* We are determining what kind of tf_conv = 1 << 6, /* We are determining what kind of
conversion might be permissible, conversion might be permissible,
not actually performing the not actually performing the
conversion. */ conversion. */
tf_no_access_control = 1 << 7, /* Do not perform access checks, even
when issuing other errors. */
/* Convenient substitution flags combinations. */ /* Convenient substitution flags combinations. */
tf_warning_or_error = tf_warning | tf_error tf_warning_or_error = tf_warning | tf_error
} tsubst_flags_t; } 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> 2008-12-09 Jakub Jelinek <jakub@redhat.com>
PR middle-end/38454 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