+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.
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);
/* 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,
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);
tf_warning_or_error);
arg = convert_for_arg_passing (type, arg);
}
+ pop_deferring_access_checks();
VEC_pop (tree, default_arg_context);
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,
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))
/* 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
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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" }
+};