cp-tree.h (BASELINK_P): New macro.
authorMark Mitchell <mark@codesourcery.com>
Tue, 6 Apr 1999 14:38:08 +0000 (14:38 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 6 Apr 1999 14:38:08 +0000 (14:38 +0000)
* cp-tree.h (BASELINK_P): New macro.
(SET_BASELINK_P): Likewise.
* init.c (build_member_call): Remove needless assignment in if
statement.
* search.c (lookup_field_r): Fix handling when we are looking
specifically for a type; these are not hidden by functions and
variables.
(lookup_member): Use SET_BASELINK_P.
* tree.c (is_overloaded_fn): Use BASELINK_P.
(really_overloaed_fn): Likewise.
(get_first_fn): Likewise.

From-SVN: r26219

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/init.c
gcc/cp/search.c
gcc/cp/tree.c
gcc/testsuite/g++.old-deja/g++.other/crash9.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/crash33.C [new file with mode: 0644]

index e5d86a99f052f178bd451d601cb06fc49ff4b7ac..5dd92144328d17335f375aaa4da90ae20bea2426 100644 (file)
@@ -1,3 +1,17 @@
+1999-04-06  Mark Mitchell  <mark@codesourcery.com>
+
+       * cp-tree.h (BASELINK_P): New macro.
+       (SET_BASELINK_P): Likewise.
+       * init.c (build_member_call): Remove needless assignment in if
+       statement.
+       * search.c (lookup_field_r): Fix handling when we are looking
+       specifically for a type; these are not hidden by functions and
+       variables.
+       (lookup_member): Use SET_BASELINK_P.
+       * tree.c (is_overloaded_fn): Use BASELINK_P.
+       (really_overloaed_fn): Likewise.
+       (get_first_fn): Likewise.
+       
 1999-04-05  Mark Mitchell  <mark@codesourcery.com>
 
        * decl.c (lookup_name_current_level): Tweak, and improve
index 6d0b2735bd23f138df3a88200ffcabd82aa25b89..0ed7d750232ecf1aebf99029d0b5f2e82c94e546 100644 (file)
@@ -33,7 +33,7 @@ Boston, MA 02111-1307, USA.  */
       TREE_INDIRECT_USING (in NAMESPACE_DECL).
       IDENTIFIER_MARKED (used by search routines).
       LOCAL_BINDING_P (in CPLUS_BINDING)
-   1:  IDENTIFIER_VIRTUAL_P.
+   1: IDENTIFIER_VIRTUAL_P.
       TI_PENDING_TEMPLATE_FLAG.
       TEMPLATE_PARMS_FOR_INLINE.
       DELETE_EXPR_USE_VEC (in DELETE_EXPR).
@@ -41,6 +41,7 @@ Boston, MA 02111-1307, USA.  */
       TYPE_USES_COMPLEX_INHERITANCE (in _TYPE).
       C_DECLARED_LABEL_FLAG.
       INHERITED_VALUE_BINDING_P (in CPLUS_BINDING)
+      BASELINK_P (in TREE_LIST)
    2: IDENTIFIER_OPNAME_P.
       BINFO_VBASE_MARKED.
       BINFO_FIELDS_MARKED.
@@ -191,6 +192,14 @@ struct tree_overload
   tree function;
 };
 
+/* A `baselink' is a TREE_LIST whose TREE_PURPOSE is a BINFO
+   indicating a particular base class, and whose TREE_VALUE is a
+   (possibly overloaded) function from that base class.  */
+#define BASELINK_P(NODE) \
+  (TREE_CODE ((NODE)) == TREE_LIST && TREE_LANG_FLAG_1 ((NODE)))
+#define SET_BASELINK_P(NODE) \
+  (TREE_LANG_FLAG_1 ((NODE)) = 1)
+
 #define WRAPPER_PTR(NODE) (((struct tree_wrapper*)NODE)->u.ptr)
 #define WRAPPER_INT(NODE) (((struct tree_wrapper*)NODE)->u.i)
 
index 062620367154429c8ec3a6c4acd51e5c4b2d7611..2769765ef635e324f558e55a248c53a9d6c3815e 100644 (file)
@@ -1443,7 +1443,7 @@ build_member_call (type, name, parmlist)
   if (method_name == constructor_name (type)
       || method_name == constructor_name_full (type))
     return build_functional_cast (type, parmlist);
-  if ((t = lookup_fnfields (basetype_path, method_name, 0)))
+  if (lookup_fnfields (basetype_path, method_name, 0))
     return build_method_call (decl, 
                              TREE_CODE (name) == TEMPLATE_ID_EXPR
                              ? name : method_name,
index 99e25a84a15e9184d27c07d696aa06f6dab95df3..7a13a9f1e0d4e865232f73735c3576fb10554339 100644 (file)
@@ -1207,17 +1207,20 @@ lookup_field_r (binfo, data)
 {
   struct lookup_field_info *lfi = (struct lookup_field_info *) data;
   tree type = BINFO_TYPE (binfo);
-  tree nval;
-  int idx;
+  tree nval = NULL_TREE;
   int from_dep_base_p;
 
   /* First, look for a function.  There can't be a function and a data
      member with the same name, and if there's a function and a type
      with the same name, the type is hidden by the function.  */
-  idx = lookup_fnfields_here (type, lfi->name);
-  if (idx >= 0)
-    nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);
-  else
+  if (!lfi->want_type)
+    {
+      int idx = lookup_fnfields_here (type, lfi->name);
+      if (idx >= 0)
+       nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);
+    }
+
+  if (!nval)
     /* Look for a data member or type.  */
     nval = lookup_field_1 (type, lfi->name);
 
@@ -1226,6 +1229,17 @@ lookup_field_r (binfo, data)
   if (!nval)
     return NULL_TREE;
 
+  /* If we're looking up a type (as with an elaborated type specifier)
+     we ignore all non-types we find.  */
+  if (lfi->want_type && TREE_CODE (nval) != TYPE_DECL)
+    {
+      nval = purpose_member (lfi->name, CLASSTYPE_TAGS (type));
+      if (nval)
+       nval = TYPE_MAIN_DECL (TREE_VALUE (nval));
+      else 
+       return NULL_TREE;
+    }
+
   /* You must name a template base class with a template-id.  */
   if (!same_type_p (type, lfi->type) 
       && template_self_reference_p (type, nval))
@@ -1285,41 +1299,24 @@ lookup_field_r (binfo, data)
     }
   else
     {
-      /* The new lookup is the best we've got so far.  Verify that
-        it's the kind of thing we're looking for.  */
-      if (lfi->want_type && TREE_CODE (nval) != TYPE_DECL)
+      /* If the thing we're looking for is a virtual base class, then
+        we know we've got what we want at this point; there's no way
+        to get an ambiguity.  */
+      if (VBASE_NAME_P (lfi->name))
        {
-         nval = purpose_member (lfi->name, CLASSTYPE_TAGS (type));
-         if (nval)
-           {
-             nval = TYPE_MAIN_DECL (TREE_VALUE (nval));
-             if (!same_type_p (type, lfi->type)
-                 && template_self_reference_p (type, nval))
-               nval = NULL_TREE;
-           }
+         lfi->rval = nval;
+         return nval;
        }
 
-      if (nval)
-       {
-         /* If the thing we're looking for is a virtual base class,
-            then we know we've got what we want at this point;
-            there's no way to get an ambiguity.  */
-         if (VBASE_NAME_P (lfi->name))
-           {
-             lfi->rval = nval;
-             return nval;
-           }
-
-         if (from_dep_base_p && TREE_CODE (nval) != TYPE_DECL
-             /* We need to return a member template class so we can
-                define partial specializations.  Is there a better
-                way?  */
-             && !DECL_CLASS_TEMPLATE_P (nval))
-           /* The thing we're looking for isn't a type, so the implicit
-              typename extension doesn't apply, so we just pretend we
-              didn't find anything.  */
-           return NULL_TREE;
-       }
+      if (from_dep_base_p && TREE_CODE (nval) != TYPE_DECL
+         /* We need to return a member template class so we can
+            define partial specializations.  Is there a better
+            way?  */
+         && !DECL_CLASS_TEMPLATE_P (nval))
+       /* The thing we're looking for isn't a type, so the implicit
+          typename extension doesn't apply, so we just pretend we
+          didn't find anything.  */
+       return NULL_TREE;
 
       lfi->rval = nval;
       lfi->from_dep_base_p = from_dep_base_p;
@@ -1444,8 +1441,11 @@ lookup_member (xbasetype, name, protect, want_type)
                                                name, name,
                                                TREE_TYPE (rval)));
 
-  if (rval && is_overloaded_fn (rval))
-    rval = scratch_tree_cons (basetype_path, rval, NULL_TREE);
+  if (rval && is_overloaded_fn (rval)) 
+    {
+      rval = scratch_tree_cons (basetype_path, rval, NULL_TREE);
+      SET_BASELINK_P (rval);
+    }
 
   return rval;
 }
index 96d9cbd72bd2d4cc84c4c34587250a3c857c2a4f..44e958f064d433de57c9f75157794091023d9806 100644 (file)
@@ -1223,21 +1223,9 @@ int
 is_overloaded_fn (x)
      tree x;
 {
-  /* XXX A baselink is also considered an overloaded function.
-     As is a placeholder from push_class_decls.
-     As is an expression like X::f.  */
-  if (TREE_CODE (x) == TREE_LIST)
-    {
-      if (TREE_PURPOSE (x) == error_mark_node)
-       {
-         x = TREE_VALUE (x);
-         my_friendly_assert (TREE_CODE (x) == TREE_LIST, 981121);
-       }
-      my_friendly_assert (TREE_CODE (TREE_PURPOSE (x)) == TREE_VEC
-                         || TREE_CODE (TREE_PURPOSE (x)) == IDENTIFIER_NODE,
-                         388);
-      x = TREE_VALUE (x);
-    }
+  /* A baselink is also considered an overloaded function.  */
+  if (BASELINK_P (x))
+    x = TREE_VALUE (x);
   return (TREE_CODE (x) == FUNCTION_DECL
          || TREE_CODE (x) == TEMPLATE_ID_EXPR
          || DECL_FUNCTION_TEMPLATE_P (x)
@@ -1248,9 +1236,8 @@ int
 really_overloaded_fn (x)
      tree x;
 {     
-  /* A baselink is also considered an overloaded function.
-     This might also be an ambiguous class member. */
-  if (TREE_CODE (x) == TREE_LIST)
+  /* A baselink is also considered an overloaded function.  */
+  if (BASELINK_P (x))
     x = TREE_VALUE (x);
   return (TREE_CODE (x) == OVERLOAD 
          && (TREE_CHAIN (x) != NULL_TREE
@@ -1263,7 +1250,7 @@ get_first_fn (from)
 {
   my_friendly_assert (is_overloaded_fn (from), 9);
   /* A baselink is also considered an overloaded function. */
-  if (TREE_CODE (from) == TREE_LIST)
+  if (BASELINK_P (from))
     from = TREE_VALUE (from);
   return OVL_CURRENT (from);
 }
diff --git a/gcc/testsuite/g++.old-deja/g++.other/crash9.C b/gcc/testsuite/g++.old-deja/g++.other/crash9.C
new file mode 100644 (file)
index 0000000..d3c2397
--- /dev/null
@@ -0,0 +1,9 @@
+// Build don't link:
+// Origin: Jason Merrill <jason@cygnus.com>
+
+struct A { };
+struct B : public A
+{
+  int A;
+};
+struct C : public B { };
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash33.C b/gcc/testsuite/g++.old-deja/g++.pt/crash33.C
new file mode 100644 (file)
index 0000000..bc7dcf5
--- /dev/null
@@ -0,0 +1,17 @@
+// Build don't link:
+// Origin: Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+class A {
+public:
+        template <class T> T& f(T& t) const;
+};
+
+class B {
+public:
+        template <class T> T& f(T& t) const;
+};
+
+class C: public A,B {
+public:
+        template <class T> T& f(T& t) const;
+};