summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2004-10-18 17:21:36 +0000
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2004-10-18 17:21:36 +0000
commitada40935ef7cd6d2300ac09d22584a87e0dcd93c (patch)
tree236c7f936b34023b8a9d3dac4bda50d439059160 /gcc/cp
parenta1f487759c3044b9471a858df8127c6136fd22a1 (diff)
downloadgcc-ada40935ef7cd6d2300ac09d22584a87e0dcd93c.tar.gz
cp:
* cp-tree.h (UNIQUELY_DERIVED_FROM_P): Adjust lookup_base call. (ACCESSIBLY_UNIQUELY_DERIVED_P): Remove. (PUBLICLY_UNIQUELY_DERIVED_P): Adjust lookup_base call. (enum base_access): Reorganize. (accessible_base_p, accessible_p): Add consider_local_p parameter. * call.c (standard_conversion): Update comment about DERIVED_FROM_P. (enforce_access): Adjust accessible_p call. (build_over_call): Adjust accessible_base_p call. * class.c (convert_to_base): Adjust lookup_base call. (build_vtbl_ref_1): Likewise. (warn_about_ambiguous_bases): Likewise. Add early exit. * cvt.c (convert_to_pointer_force) Adjust lookup_base call. * search.c (accessible_base_p): Add consider_local_p parameter. (lookup_base): Pass consider_local_p to accessible_base_p call. (friend_accessible_p): Check whether scope is a class member. Remove unnecessary class template check. (accessible_p): Add consider_local_p parameter. Use it. (adjust_result_of_qualified_name_lookup): Adjust lookup_base call. * tree.c (maybe_dummy_object): Likewise. * typeck.c (comp_except_type): Use PUBLICLY_UNIQUELY_DERIVED_P. (build_class_member_access_expr): Adjust lookup_base call. * typeck2.c (binfo_or_else): Likewise. * rtti.c (build_dynamic_cast_1): Access can consider friendship and current scope. testsuite: * g++.dg/eh/shadow1.C: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@89232 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog28
-rw-r--r--gcc/cp/call.c12
-rw-r--r--gcc/cp/class.c12
-rw-r--r--gcc/cp/cp-tree.h26
-rw-r--r--gcc/cp/cvt.c4
-rw-r--r--gcc/cp/rtti.c2
-rw-r--r--gcc/cp/search.c73
-rw-r--r--gcc/cp/tree.c2
-rw-r--r--gcc/cp/typeck.c4
-rw-r--r--gcc/cp/typeck2.c2
10 files changed, 95 insertions, 70 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3e5f7433129..fa85757b919 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,31 @@
+2004-10-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (UNIQUELY_DERIVED_FROM_P): Adjust lookup_base call.
+ (ACCESSIBLY_UNIQUELY_DERIVED_P): Remove.
+ (PUBLICLY_UNIQUELY_DERIVED_P): Adjust lookup_base call.
+ (enum base_access): Reorganize.
+ (accessible_base_p, accessible_p): Add consider_local_p parameter.
+ * call.c (standard_conversion): Update comment about
+ DERIVED_FROM_P.
+ (enforce_access): Adjust accessible_p call.
+ (build_over_call): Adjust accessible_base_p call.
+ * class.c (convert_to_base): Adjust lookup_base call.
+ (build_vtbl_ref_1): Likewise.
+ (warn_about_ambiguous_bases): Likewise. Add early exit.
+ * cvt.c (convert_to_pointer_force) Adjust lookup_base call.
+ * search.c (accessible_base_p): Add consider_local_p parameter.
+ (lookup_base): Pass consider_local_p to accessible_base_p call.
+ (friend_accessible_p): Check whether scope is a class member.
+ Remove unnecessary class template check.
+ (accessible_p): Add consider_local_p parameter. Use it.
+ (adjust_result_of_qualified_name_lookup): Adjust lookup_base call.
+ * tree.c (maybe_dummy_object): Likewise.
+ * typeck.c (comp_except_type): Use PUBLICLY_UNIQUELY_DERIVED_P.
+ (build_class_member_access_expr): Adjust lookup_base call.
+ * typeck2.c (binfo_or_else): Likewise.
+ * rtti.c (build_dynamic_cast_1): Access can consider friendship
+ and current scope.
+
2004-10-17 Giovanni Bajo <giovannibajo@gcc.gnu.org>
PR c++/17743
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 7d4e9634e4c..f15fd2ccb4a 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -711,9 +711,9 @@ standard_conversion (tree to, tree from, tree expr)
_class.derived_) of D. If B is an inaccessible
(clause _class.access_) or ambiguous
(_class.member.lookup_) base class of D, a program
- that necessitates this conversion is ill-formed. */
- /* Therefore, we use DERIVED_FROM_P, and not
- ACCESSIBLY_UNIQUELY_DERIVED_FROM_P, in this test. */
+ that necessitates this conversion is ill-formed.
+ Therefore, we use DERIVED_FROM_P, and do not check
+ access or uniqueness. */
&& DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
{
from =
@@ -4051,7 +4051,7 @@ enforce_access (tree basetype_path, tree decl)
{
gcc_assert (TREE_CODE (basetype_path) == TREE_BINFO);
- if (!accessible_p (basetype_path, decl))
+ if (!accessible_p (basetype_path, decl, true))
{
if (TREE_PRIVATE (decl))
cp_error_at ("%q+#D is private", decl);
@@ -4670,7 +4670,7 @@ build_over_call (struct z_candidate *cand, int flags)
1);
/* Check that the base class is accessible. */
if (!accessible_base_p (TREE_TYPE (argtype),
- BINFO_TYPE (cand->conversion_path)))
+ BINFO_TYPE (cand->conversion_path), true))
error ("%qT is not an accessible base of %qT",
BINFO_TYPE (cand->conversion_path),
TREE_TYPE (argtype));
@@ -4678,7 +4678,7 @@ build_over_call (struct z_candidate *cand, int flags)
will be to the derived class, not the base declaring fn. We
must convert from derived to base. */
base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)),
- TREE_TYPE (parmtype), ba_ignore, NULL);
+ TREE_TYPE (parmtype), ba_unique, NULL);
converted_arg = build_base_path (PLUS_EXPR, converted_arg,
base_binfo, 1);
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index b1eec83b607..a0a2ed48bce 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -436,7 +436,7 @@ convert_to_base (tree object, tree type, bool check_access)
tree binfo;
binfo = lookup_base (TREE_TYPE (object), type,
- check_access ? ba_check : ba_ignore,
+ check_access ? ba_check : ba_unique,
NULL);
if (!binfo || binfo == error_mark_node)
return error_mark_node;
@@ -526,7 +526,7 @@ build_vtbl_ref_1 (tree instance, tree idx)
if (fixed_type && !cdtorp)
{
tree binfo = lookup_base (fixed_type, basetype,
- ba_ignore|ba_quiet, NULL);
+ ba_unique | ba_quiet, NULL);
if (binfo)
vtbl = unshare_expr (BINFO_VTABLE (binfo));
}
@@ -4392,13 +4392,17 @@ warn_about_ambiguous_bases (tree t)
tree binfo;
tree base_binfo;
+ /* If there are no repeated bases, nothing can be ambiguous. */
+ if (!CLASSTYPE_REPEATED_BASE_P (t))
+ return;
+
/* Check direct bases. */
for (binfo = TYPE_BINFO (t), i = 0;
BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
{
basetype = BINFO_TYPE (base_binfo);
- if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL))
+ if (!lookup_base (t, basetype, ba_unique | ba_quiet, NULL))
warning ("direct base %qT inaccessible in %qT due to ambiguity",
basetype, t);
}
@@ -4410,7 +4414,7 @@ warn_about_ambiguous_bases (tree t)
{
basetype = BINFO_TYPE (binfo);
- if (!lookup_base (t, basetype, ba_ignore | ba_quiet, NULL))
+ if (!lookup_base (t, basetype, ba_unique | ba_quiet, NULL))
warning ("virtual base %qT inaccessible in %qT due to ambiguity",
basetype, t);
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 2350ab0d60f..b6c976baaa8 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -924,15 +924,11 @@ enum languages { lang_c, lang_cplusplus, lang_java };
/* Nonzero iff TYPE is uniquely derived from PARENT. Ignores
accessibility. */
#define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) \
- (lookup_base ((TYPE), (PARENT), ba_ignore | ba_quiet, NULL) != NULL_TREE)
-/* Nonzero iff TYPE is accessible in the current scope and uniquely
- derived from PARENT. */
-#define ACCESSIBLY_UNIQUELY_DERIVED_P(PARENT, TYPE) \
- (lookup_base ((TYPE), (PARENT), ba_check | ba_quiet, NULL) != NULL_TREE)
+ (lookup_base ((TYPE), (PARENT), ba_unique | ba_quiet, NULL) != NULL_TREE)
/* Nonzero iff TYPE is publicly & uniquely derived from PARENT. */
#define PUBLICLY_UNIQUELY_DERIVED_P(PARENT, TYPE) \
- (lookup_base ((TYPE), (PARENT), ba_not_special | ba_quiet, NULL) \
- != NULL_TREE)
+ (lookup_base ((TYPE), (PARENT), ba_ignore_scope | ba_check | ba_quiet, \
+ NULL) != NULL_TREE)
/* Gives the visibility specification for a class type. */
#define CLASSTYPE_VISIBILITY(TYPE) \
@@ -2972,13 +2968,13 @@ typedef enum tsubst_flags_t {
/* The kind of checking we can do looking in a class hierarchy. */
typedef enum base_access {
- ba_any = 0, /* Do not check access, allow an ambiguous base,
+ ba_any = 0, /* Do not check access, allow an ambiguous base,
prefer a non-virtual base */
- ba_ignore = 1, /* Do not check access */
- ba_check = 2, /* Check access */
- ba_not_special = 3, /* Do not consider special privilege
- current_class_type might give. */
- ba_quiet = 4 /* Do not issue error messages (bit mask). */
+ ba_unique = 1 << 0, /* Must be a unique base. */
+ ba_check_bit = 1 << 1, /* Check access. */
+ ba_check = ba_unique | ba_check_bit,
+ ba_ignore_scope = 1 << 2, /* Ignore access allowed by local scope. */
+ ba_quiet = 1 << 3 /* Do not issue error messages. */
} base_access;
/* The various kinds of access check during parsing. */
@@ -3999,10 +3995,10 @@ extern void emit_support_tinfos (void);
extern bool emit_tinfo_decl (tree);
/* in search.c */
-extern bool accessible_base_p (tree, tree);
+extern bool accessible_base_p (tree, tree, bool);
extern tree lookup_base (tree, tree, base_access, base_kind *);
extern tree dcast_base_hint (tree, tree);
-extern int accessible_p (tree, tree);
+extern int accessible_p (tree, tree, bool);
extern tree lookup_field_1 (tree, tree, bool);
extern tree lookup_field (tree, tree, int, bool);
extern int lookup_fnfields_1 (tree, tree);
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index a5d42e463e5..8e9cb957155 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -327,11 +327,11 @@ convert_to_pointer_force (tree type, tree expr)
tree binfo;
binfo = lookup_base (TREE_TYPE (intype), TREE_TYPE (type),
- ba_ignore, NULL);
+ ba_unique, NULL);
if (!binfo)
{
binfo = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
- ba_ignore, NULL);
+ ba_unique, NULL);
code = MINUS_EXPR;
}
if (binfo == error_mark_node)
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index a0711466ac9..9bb2c364bbf 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -524,7 +524,7 @@ build_dynamic_cast_1 (tree type, tree expr)
tree binfo;
binfo = lookup_base (TREE_TYPE (exprtype), TREE_TYPE (type),
- ba_not_special, NULL);
+ ba_check, NULL);
if (binfo)
{
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 79e0cc3fecf..5b060da5b28 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -150,10 +150,12 @@ dfs_lookup_base (tree binfo, void *data_)
}
/* Returns true if type BASE is accessible in T. (BASE is known to be
- a (possibly non-proper) base class of T.) */
+ a (possibly non-proper) base class of T.) If CONSIDER_LOCAL_P is
+ true, consider any special access of the current scope, or access
+ bestowed by friendship. */
bool
-accessible_base_p (tree t, tree base)
+accessible_base_p (tree t, tree base, bool consider_local_p)
{
tree decl;
@@ -173,7 +175,7 @@ accessible_base_p (tree t, tree base)
decl = TREE_CHAIN (decl);
while (ANON_AGGR_TYPE_P (t))
t = TYPE_CONTEXT (t);
- return accessible_p (t, decl);
+ return accessible_p (t, decl, consider_local_p);
}
/* Lookup BASE in the hierarchy dominated by T. Do access checking as
@@ -259,7 +261,7 @@ lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr)
break;
default:
- if ((access & ~ba_quiet) != ba_ignore
+ if ((access & ba_check_bit)
/* If BASE is incomplete, then BASE and TYPE are probably
the same, in which case BASE is accessible. If they
are not the same, then TYPE is invalid. In that case,
@@ -267,7 +269,7 @@ lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr)
there's no implicit typedef to use in the code that
follows, so we skip the check. */
&& COMPLETE_TYPE_P (base)
- && !accessible_base_p (t, base))
+ && !accessible_base_p (t, base, !(access & ba_ignore_scope)))
{
if (!(access & ba_quiet))
{
@@ -806,7 +808,7 @@ friend_accessible_p (tree scope, tree decl, tree binfo)
{
/* Perhaps this SCOPE is a member of a class which is a
friend. */
- if (DECL_CLASS_SCOPE_P (decl)
+ if (DECL_CLASS_SCOPE_P (scope)
&& friend_accessible_p (DECL_CONTEXT (scope), decl, binfo))
return 1;
@@ -822,16 +824,6 @@ friend_accessible_p (tree scope, tree decl, tree binfo)
return ret;
}
}
- else if (CLASSTYPE_TEMPLATE_INFO (scope))
- {
- int ret;
- /* Increment processing_template_decl to make sure that
- dependent_type_p works correctly. */
- ++processing_template_decl;
- ret = friend_accessible_p (CLASSTYPE_TI_TEMPLATE (scope), decl, binfo);
- --processing_template_decl;
- return ret;
- }
return 0;
}
@@ -852,13 +844,14 @@ dfs_accessible_post (tree binfo, void *data ATTRIBUTE_UNUSED)
class used to name DECL. Return nonzero if, in the current
context, DECL is accessible. If TYPE is actually a BINFO node,
then we can tell in what context the access is occurring by looking
- at the most derived class along the path indicated by BINFO. */
+ at the most derived class along the path indicated by BINFO. If
+ CONSIDER_LOCAL is true, do consider special access the current
+ scope or friendship thereof we might have. */
int
-accessible_p (tree type, tree decl)
+accessible_p (tree type, tree decl, bool consider_local_p)
{
tree binfo;
- tree t;
tree scope;
access_kind access;
@@ -910,15 +903,19 @@ accessible_p (tree type, tree decl)
We walk the base class hierarchy, checking these conditions. */
- /* Figure out where the reference is occurring. Check to see if
- DECL is private or protected in this scope, since that will
- determine whether protected access is allowed. */
- if (current_class_type)
- protected_ok = protected_accessible_p (decl, current_class_type, binfo);
+ if (consider_local_p)
+ {
+ /* Figure out where the reference is occurring. Check to see if
+ DECL is private or protected in this scope, since that will
+ determine whether protected access is allowed. */
+ if (current_class_type)
+ protected_ok = protected_accessible_p (decl,
+ current_class_type, binfo);
- /* Now, loop through the classes of which we are a friend. */
- if (!protected_ok)
- protected_ok = friend_accessible_p (scope, decl, binfo);
+ /* Now, loop through the classes of which we are a friend. */
+ if (!protected_ok)
+ protected_ok = friend_accessible_p (scope, decl, binfo);
+ }
/* Standardize the binfo that access_in_type will use. We don't
need to know what path was chosen from this point onwards. */
@@ -930,15 +927,15 @@ accessible_p (tree type, tree decl)
if (access == ak_public
|| (access == ak_protected && protected_ok))
return 1;
- else
- {
- /* Walk the hierarchy again, looking for a base class that allows
- access. */
- t = dfs_walk_once_accessible (binfo, /*friends=*/true,
- NULL, dfs_accessible_post, NULL);
-
- return t != NULL_TREE;
- }
+
+ if (!consider_local_p)
+ return 0;
+
+ /* Walk the hierarchy again, looking for a base class that allows
+ access. */
+ return dfs_walk_once_accessible (binfo, /*friends=*/true,
+ NULL, dfs_accessible_post, NULL)
+ != NULL_TREE;
}
struct lookup_field_info {
@@ -1486,13 +1483,13 @@ adjust_result_of_qualified_name_lookup (tree decl,
or ambiguity -- in either case, the choice of a static member
function might make the usage valid. */
base = lookup_base (context_class, qualifying_scope,
- ba_ignore | ba_quiet, NULL);
+ ba_unique | ba_quiet, NULL);
if (base)
{
BASELINK_ACCESS_BINFO (decl) = base;
BASELINK_BINFO (decl)
= lookup_base (base, BINFO_TYPE (BASELINK_BINFO (decl)),
- ba_ignore | ba_quiet,
+ ba_unique | ba_quiet,
NULL);
}
}
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 134da23ffd5..afe42e23730 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1661,7 +1661,7 @@ maybe_dummy_object (tree type, tree* binfop)
if (current_class_type
&& (binfo = lookup_base (current_class_type, type,
- ba_ignore | ba_quiet, NULL)))
+ ba_unique | ba_quiet, NULL)))
context = current_class_type;
else
{
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index dc0b7cd52c5..cb5a2548d8b 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -797,7 +797,7 @@ comp_except_types (tree a, tree b, bool exact)
|| TREE_CODE (b) != RECORD_TYPE)
return false;
- if (ACCESSIBLY_UNIQUELY_DERIVED_P (a, b))
+ if (PUBLICLY_UNIQUELY_DERIVED_P (a, b))
return true;
}
return false;
@@ -1689,7 +1689,7 @@ build_class_member_access_expr (tree object, tree member,
base_kind kind;
binfo = lookup_base (access_path ? access_path : object_type,
- member_scope, ba_ignore, &kind);
+ member_scope, ba_unique, &kind);
if (binfo == error_mark_node)
return error_mark_node;
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 758f5f06de6..d28949c55bf 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -56,7 +56,7 @@ error_not_base_type (tree basetype, tree type)
tree
binfo_or_else (tree base, tree type)
{
- tree binfo = lookup_base (type, base, ba_ignore, NULL);
+ tree binfo = lookup_base (type, base, ba_unique, NULL);
if (binfo == error_mark_node)
return NULL_TREE;