From f7d042e2738fd5382cbdcb3284c237968fda4149 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 4 Nov 2010 11:52:18 -0400 Subject: [PATCH] semantics.c (speculative_access_check): New. * semantics.c (speculative_access_check): New. * cp-tree.h: Declare it. * call.c (build_over_call): Use it. * class.c (type_has_constexpr_default_constructor): Use locate_ctor. * method.c (locate_ctor): Use push/pop_deferring_access_checks. From-SVN: r166317 --- gcc/cp/ChangeLog | 8 +++++++ gcc/cp/call.c | 12 +++------- gcc/cp/class.c | 2 +- gcc/cp/cp-tree.h | 1 + gcc/cp/method.c | 8 +++++-- gcc/cp/semantics.c | 24 +++++++++++++++++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/g++.dg/cpp0x/constexpr-access.C | 14 +++++++++++ 8 files changed, 61 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-access.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c432ca8150c..ab00a0f12ff 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2010-11-04 Jason Merrill + + * semantics.c (speculative_access_check): New. + * cp-tree.h: Declare it. + * call.c (build_over_call): Use it. + * class.c (type_has_constexpr_default_constructor): Use locate_ctor. + * method.c (locate_ctor): Use push/pop_deferring_access_checks. + 2010-11-03 Jason Merrill PR c++/46293 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 4507f3d37b9..eb7247dad93 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5823,15 +5823,9 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) access_fn = fn; if (flags & LOOKUP_SPECULATIVE) { - /* If we're checking for implicit delete, we don't want access - control errors. */ - if (!accessible_p (cand->access_path, access_fn, true)) - { - /* Unless we're under maybe_explain_implicit_delete. */ - if (flags & LOOKUP_COMPLAIN) - enforce_access (cand->access_path, access_fn, fn); - return error_mark_node; - } + if (!speculative_access_check (cand->access_path, access_fn, fn, + !!(flags & LOOKUP_COMPLAIN))) + return error_mark_node; } else perform_or_defer_access_check (cand->access_path, access_fn, fn); diff --git a/gcc/cp/class.c b/gcc/cp/class.c index ded0a039972..435fa71c3f5 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -4349,7 +4349,7 @@ type_has_constexpr_default_constructor (tree t) return false; if (CLASSTYPE_LAZY_DEFAULT_CTOR (t)) return synthesized_default_constructor_is_constexpr (t); - fns = get_default_ctor (t); + fns = locate_ctor (t); return (fns && DECL_DECLARED_CONSTEXPR_P (fns)); } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index fc4772d7403..8f5227800f5 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5192,6 +5192,7 @@ extern void pop_to_parent_deferring_access_checks (void); extern void perform_access_checks (VEC (deferred_access_check,gc)*); extern void perform_deferred_access_checks (void); extern void perform_or_defer_access_check (tree, tree, tree); +extern bool speculative_access_check (tree, tree, tree, bool); extern int stmts_are_full_exprs_p (void); extern void init_cp_semantics (void); extern tree do_poplevel (tree); diff --git a/gcc/cp/method.c b/gcc/cp/method.c index ca5964e35ae..c1d30d476a1 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -849,8 +849,12 @@ get_dtor (tree type) tree locate_ctor (tree type) { - tree fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE, - LOOKUP_SPECULATIVE, tf_none); + tree fn; + + push_deferring_access_checks (dk_no_check); + fn = locate_fn_flags (type, complete_ctor_identifier, NULL_TREE, + LOOKUP_SPECULATIVE, tf_none); + pop_deferring_access_checks (); if (fn == error_mark_node) return NULL_TREE; return fn; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 9061a89ed24..3d62cd19306 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -337,6 +337,30 @@ perform_or_defer_access_check (tree binfo, tree decl, tree diag_decl) new_access->diag_decl = diag_decl; } +/* Used by build_over_call in LOOKUP_SPECULATIVE mode: return whether DECL + is accessible in BINFO, and possibly complain if not. If we're not + checking access, everything is accessible. */ + +bool +speculative_access_check (tree binfo, tree decl, tree diag_decl, + bool complain) +{ + if (deferred_access_no_check) + return true; + + /* If we're checking for implicit delete, we don't want access + control errors. */ + if (!accessible_p (binfo, decl, true)) + { + /* Unless we're under maybe_explain_implicit_delete. */ + if (complain) + enforce_access (binfo, decl, diag_decl); + return false; + } + + return true; +} + /* Returns nonzero if the current statement is a full expression, i.e. temporaries created during that statement should be destroyed at the end of the statement. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6928ea0b184..0fa52176934 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-11-04 Jason Merrill + + * g++.dg/cpp0x/constexpr-access.C: New. + 2010-11-04 Richard Guenther PR rtl-optimization/46183 diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-access.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-access.C new file mode 100644 index 00000000000..ee5fc9854fc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-access.C @@ -0,0 +1,14 @@ +// { dg-options -std=c++0x } + +class base +{ +protected: + constexpr base() { } +}; + +struct A : base { }; + +int main() +{ + A a; +}