aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@markmitchell.com>1999-02-26 12:00:10 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-02-26 12:00:10 +0000
commited70c42623729d86d2dc610a5279a5f394be68ee (patch)
treebdf499e8f2baf8ac571c9d16b451fb1e822edbcd /gcc
parentf3d50f4227003ecc718cd59376bacfade9dd2c46 (diff)
downloadgcc-ed70c42623729d86d2dc610a5279a5f394be68ee.zip
gcc-ed70c42623729d86d2dc610a5279a5f394be68ee.tar.gz
gcc-ed70c42623729d86d2dc610a5279a5f394be68ee.tar.bz2
class.c (check_for_override): Don't stop checking when we find the first overridden function.
* 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. From-SVN: r25457
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/class.c31
-rw-r--r--gcc/cp/search.c14
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/virtual4.C25
4 files changed, 50 insertions, 26 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b0ef37c..e9f87d7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 7e91612..3fc9cf4 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 33842c6..6c046ed 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -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
index 0000000..8a44ee1
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/virtual4.C
@@ -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
+};