aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/call.c12
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/method.c8
-rw-r--r--gcc/cp/semantics.c24
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-access.C14
8 files changed, 61 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c432ca8..ab00a0f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2010-11-04 Jason Merrill <jason@redhat.com>
+
+ * 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 <jason@redhat.com>
PR c++/46293
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 4507f3d..eb7247d 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 ded0a03..435fa71 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 fc4772d..8f52278 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 ca5964e..c1d30d4 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 9061a89..3d62cd1 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 6928ea0..0fa5217 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2010-11-04 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/cpp0x/constexpr-access.C: New.
+
2010-11-04 Richard Guenther <rguenther@suse.de>
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 0000000..ee5fc98
--- /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;
+}