diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2004-10-18 17:21:36 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2004-10-18 17:21:36 +0000 |
commit | 18e4be8561b8aee3937528dd27635eaf761e57d0 (patch) | |
tree | 236c7f936b34023b8a9d3dac4bda50d439059160 /gcc | |
parent | b499264121070eb0876ab645d34bea38493c1821 (diff) | |
download | gcc-18e4be8561b8aee3937528dd27635eaf761e57d0.zip gcc-18e4be8561b8aee3937528dd27635eaf761e57d0.tar.gz gcc-18e4be8561b8aee3937528dd27635eaf761e57d0.tar.bz2 |
cp-tree.h (UNIQUELY_DERIVED_FROM_P): Adjust lookup_base call.
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.
From-SVN: r89232
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 28 | ||||
-rw-r--r-- | gcc/cp/call.c | 12 | ||||
-rw-r--r-- | gcc/cp/class.c | 12 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 26 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 4 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 2 | ||||
-rw-r--r-- | gcc/cp/search.c | 73 | ||||
-rw-r--r-- | gcc/cp/tree.c | 2 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 4 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/eh/shadow1.C | 32 |
12 files changed, 131 insertions, 70 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3e5f743..fa85757 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 7d4e963..f15fd2c 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 b1eec83..a0a2ed4 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 2350ab0..b6c976b 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 a5d42e4..8e9cb95 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 a071146..9bb2c36 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 79e0cc3..5b060da5 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 134da23..afe42e2 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 dc0b7cd..cb5a254 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 758f5f0..d28949c 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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0b2038a..146312b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-10-18 Nathan Sidwell <nathan@codesourcery.com> + + * g++.dg/eh/shadow1.C: New. + 2004-10-18 Jakub Jelinek <jakub@redhat.com> * gcc.c-torture/compile/20041018-1.c: New test. diff --git a/gcc/testsuite/g++.dg/eh/shadow1.C b/gcc/testsuite/g++.dg/eh/shadow1.C new file mode 100644 index 0000000..15f666a --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/shadow1.C @@ -0,0 +1,32 @@ +// Copyright (C) 2004 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 15 Oct 2004 <nathan@codesourcery.com> + +// We forgot to ignore current context and friends when determing +// which exceptions shadowed eachother. + +struct E; + +struct B {}; + +struct D : private B +{ + friend class E; + + static B *baz (D *); + virtual void V () throw (B); // { dg-error "overriding" "" } +}; + +struct E : public D +{ + virtual void V () throw (D); // { dg-error "looser throw" "" } +}; + +B* foo (D *); + +B *D::baz (D *p) +{ + try {foo (p);} + catch (B const &b) {} + catch (D const &d) {} + return p; +} |