]> gcc.gnu.org Git - gcc.git/commitdiff
cp-tree.h (UNIQUELY_DERIVED_FROM_P): Adjust lookup_base call.
authorNathan Sidwell <nathan@codesourcery.com>
Mon, 18 Oct 2004 17:21:36 +0000 (17:21 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Mon, 18 Oct 2004 17:21:36 +0000 (17:21 +0000)
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

12 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/rtti.c
gcc/cp/search.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/eh/shadow1.C [new file with mode: 0644]

index 3e5f74331295c290c3d049e9e99b99a41b9716f3..fa85757b919c4af009403ea9d5e99793984f4d26 100644 (file)
@@ -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
index 7d4e9634e4c0f6fedd5a14d3a4a909455d86253e..f15fd2ccb4a8aa436ef5a837ff4ec5d3175d0f62 100644 (file)
@@ -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);
       
index b1eec83b6077ebb3f64ef038455981cf39a6f81a..a0a2ed48bce11628dc1add33d83183f7f9aa9079 100644 (file)
@@ -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);
       }
index 2350ab0d60f22b93c3f1923e72994d57c357956f..b6c976baaa8c6d7262f3ec9c25543a6416659ad2 100644 (file)
@@ -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);
index a5d42e463e57c6c2bea9ac480462246fbcaa0a73..8e9cb9571558d926438e111e1623d8f3c6b022d5 100644 (file)
@@ -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)
index a0711466ac9847eb2463493e4d4f137d523dc2d8..9bb2c364bbff41accfd541d1aad6ab1f34adddc1 100644 (file)
@@ -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)
       {
index 79e0cc3fecf8061350ef2fb55e73c12bf61d6312..5b060da5b2806faebb281face27efb4bb878a05a 100644 (file)
@@ -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);
        }
     }
index 134da23ffd5aa6e7f1df9c56b8c54069634a8785..afe42e23730cb8cf8c2dc17333b12d671d6d72cc 100644 (file)
@@ -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
     {
index dc0b7cd52c59aed70f14eeafd6e9b962a75a8411..cb5a2548d8b5ea56b36f97c79cafceabb8581cd4 100644 (file)
@@ -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;
 
index 758f5f06de6bcbecdc8b5b05fbcb6d4624c5de05..d28949c55bfd23caa8a63745028d6544d81984d3 100644 (file)
@@ -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;
index 0b2038a73c6767f482a9928ba5a2f4eacde92fd5..146312b98b204f3da74b58cbf9e9892c2017c6ee 100644 (file)
@@ -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 (file)
index 0000000..15f666a
--- /dev/null
@@ -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;
+}
This page took 0.09881 seconds and 5 git commands to generate.