OSDN Git Service

* class.c (check_for_override): Don't stop checking when we find
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 26 Feb 1999 12:00:10 +0000 (12:00 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 26 Feb 1999 12:00:10 +0000 (12:00 +0000)
the first overridden function.  Delete #if 0'd code.
* search.c (get_matching_virtual): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@25457 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/search.c
gcc/testsuite/g++.old-deja/g++.other/virtual4.C [new file with mode: 0644]

index b0ef37c..e9f87d7 100644 (file)
@@ -1,3 +1,9 @@
+1999-02-26  Mark Mitchell  <mark@markmitchell.com>
+
+       * class.c (check_for_override): Don't stop checking when we find
+       the first overridden function.  Delete #if 0'd code.
+       * search.c (get_matching_virtual): Likewise.
+       
 1999-02-25  Richard Henderson  <rth@cygnus.com>
 
        * lang-specs.h: Define __FAST_MATH__ when appropriate.
index 7e91612..3fc9cf4 100644 (file)
@@ -2991,6 +2991,7 @@ check_for_override (decl, ctype)
   tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype));
   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
   int virtualp = DECL_VIRTUAL_P (decl);
+  int found_overriden_fn = 0;
 
   for (i = 0; i < n_baselinks; i++)
     {
@@ -3000,7 +3001,8 @@ check_for_override (decl, ctype)
          tree tmp = get_matching_virtual
            (base_binfo, decl,
             DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)));
-         if (tmp)
+
+         if (tmp && !found_overriden_fn)
            {
              /* If this function overrides some virtual in some base
                 class, then the function itself is also necessarily
@@ -3021,26 +3023,15 @@ check_for_override (decl, ctype)
                }
              virtualp = 1;
 
-#if 0 /* The signature of an overriding function is not changed.  */
-             {
-               /* The argument types may have changed...  */
-               tree type = TREE_TYPE (decl);
-               tree argtypes = TYPE_ARG_TYPES (type);
-               tree base_variant = TREE_TYPE (TREE_VALUE (argtypes));
-               tree raises = TYPE_RAISES_EXCEPTIONS (type);
-
-               argtypes = commonparms (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (tmp))),
-                                       TREE_CHAIN (argtypes));
-               /* But the return type has not.  */
-               type = build_cplus_method_type (base_variant, TREE_TYPE (type), argtypes);
-               if (raises)
-                 type = build_exception_variant (type, raises);
-               TREE_TYPE (decl) = type;
-             }
-#endif
              DECL_VINDEX (decl)
                = tree_cons (NULL_TREE, tmp, DECL_VINDEX (decl));
-             break;
+             
+             /* We now know that DECL overrides something,
+                which is all that is important.  But, we must
+                continue to iterate through all the base-classes
+                in order to allow get_matching_virtual to check for
+                various illegal overrides.  */
+             found_overriden_fn = 1;
            }
        }
     }
@@ -4897,6 +4888,8 @@ push_nested_class (type, modify)
 {
   tree context;
 
+  my_friendly_assert (!type || TREE_CODE (type) != NAMESPACE_DECL, 980711);
+
   /* A namespace might be passed in error cases, like A::B:C.  */
   if (type == NULL_TREE || type == error_mark_node || ! IS_AGGR_TYPE (type)
       || TREE_CODE (type) == NAMESPACE_DECL
index 33842c6..6c046ed 100644 (file)
@@ -1887,15 +1887,15 @@ get_matching_virtual (binfo, fndecl, dtorp)
                      cp_error_at ("  overriding definition as `%#D'", tmp);
                      SET_IDENTIFIER_ERROR_LOCUS (name, basetype);
                    }
-                 break;
+
+                 /* FNDECL overrides this function.  We continue to
+                    check all the other functions in order to catch
+                    errors; it might be that in some other baseclass
+                    a virtual function was declared with the same
+                    parameter types, but a different return type.  */
+                 best = tmp;
                }
            }
-         /* If not at the end */
-         if (tmps)
-           {
-             best = tmp;
-             break;
-           }
        }
 
       return best;
diff --git a/gcc/testsuite/g++.old-deja/g++.other/virtual4.C b/gcc/testsuite/g++.old-deja/g++.other/virtual4.C
new file mode 100644 (file)
index 0000000..8a44ee1
--- /dev/null
@@ -0,0 +1,25 @@
+// Build don't link:
+
+class A {
+public:
+  virtual int foo() = 0; // ERROR - original definition
+};
+
+class B {
+public:
+    virtual double foo() = 0;
+};
+
+class C
+  : public A, public B
+{
+public:
+  virtual double foo() { return 2; } // ERROR - conflicting return type
+};
+
+class D
+  : public B, public A
+{
+public:
+  virtual double foo() { return 2; } // ERROR - conflicting return type
+};