From 248e1b22b25685386d34956368cb80c707a22a2f Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Wed, 10 Dec 2008 01:23:28 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 11 +++++++++ gcc/cp/call.c | 22 +++++++++++++----- gcc/cp/class.c | 28 ++++++++++++++--------- gcc/cp/cp-tree.h | 30 +++++++++++++------------ gcc/testsuite/ChangeLog | 6 +++++ gcc/testsuite/g++.dg/overload/defarg2.C | 17 ++++++++++++++ gcc/testsuite/g++.dg/overload/defarg3.C | 15 +++++++++++++ 7 files changed, 99 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/g++.dg/overload/defarg2.C create mode 100644 gcc/testsuite/g++.dg/overload/defarg3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 98cb9d744c7..9c27cd04b85 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2008-12-09 Mark Mitchell + + 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 * decl2.c (mark_used): Remove assemble_external call. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 273599eddfc..952e151f94b 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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); diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 97ab9e38b87..805e51322e8 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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)) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 7f33ff139b4..bf22eb4d85f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6f8449a5ea3..3a14097d584 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2008-12-09 Mark Mitchell + + PR c++/37971 + * g++.dg/overload/defarg2.C: New test. + * g++.dg/overload/defarg3.C: Likewise. + 2008-12-09 Jakub Jelinek PR middle-end/38454 diff --git a/gcc/testsuite/g++.dg/overload/defarg2.C b/gcc/testsuite/g++.dg/overload/defarg2.C new file mode 100644 index 00000000000..6b1a423dd0a --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/defarg2.C @@ -0,0 +1,17 @@ +// 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(); +} diff --git a/gcc/testsuite/g++.dg/overload/defarg3.C b/gcc/testsuite/g++.dg/overload/defarg3.C new file mode 100644 index 00000000000..83ee111f15e --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/defarg3.C @@ -0,0 +1,15 @@ +// 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" } +}; -- 2.30.2