This is actually a (was: Re:) Patch for better diagnostic (was: Re: Bug in MI?))
Manfred Hollstein
manfred@s-direktnet.de
Tue Mar 10 03:34:00 GMT 1998
On Mon, 9 March 1998, 10:03:27, manfred@s-direktnet.de wrote:
> On , 9 March 1998, 00:56:41, jason@cygnus.com wrote:
>
> > >>>>> Manfred Hollstein <manfred@s-direktnet.de> writes:
> >
> > >> That can't be right; you can't treat error_mark_node like a TREE_LIST.
> >
> > > Perhaps, you're wright. But that treatment isn't new due to my patch. I only
> > > added the the different error message, the while loop was already there.
> >
> > Agreed. The old code didn't recognize that we could get an error_mark_node
> > there. Do you mind fixing it?
>
> Oops, do you like _me_ to fix it, or what? I'll take a look, see what I can
> do.
How about this patch? It runs twice over the TREE_LIST (as Alexandre suggested)
to first list real abstract functions, then functions that need a final overrider.
Given the example program
// File: t.cc
struct B
{
virtual int fo ();
virtual int av () = 0;
};
struct D1 : virtual public B
{
virtual int fo ();
};
struct D2 : virtual public B
{
virtual int fo ();
};
struct D : virtual public D1, virtual public D2
{ };
main ()
{
B *p1 = new D;
B *p2 = new D;
}
// End of file: t.cc
then results in:
$ gcc -c t.cc
t.cc: In function `int main()':
t.cc:22: cannot allocate an object of type `D'
t.cc:22: since the following virtual functions are abstract:
t.cc:22: int B::av()
t.cc:22: and the following virtual functions need a final overrider:
t.cc:22: int D1::fo()
t.cc:23: cannot allocate an object of type `D'
t.cc:23: since type `D' has abstract virtual functions and must override virtual functions
Commenting the abstract function av gives:
t.cc: In function `int main()':
t.cc:22: cannot allocate an object of type `D'
t.cc:22: since the following virtual functions need a final overrider:
t.cc:22: int D1::fo()
t.cc:23: cannot allocate an object of type `D'
t.cc:23: since type `D' must override virtual functions
Tue Mar 10 12:13:50 1998 Manfred Hollstein <manfred@s-direktnet.de>
* cp-tree.h (struct lang_decl_flags): Add needs_final_overrider.
(DECL_NEEDS_FINAL_OVERRIDER_P): New macro.
* class.c (override_one_vtable): Set DECL_NEEDS_FINAL_OVERRIDER_P.
* decl.c (duplicate_decls): Propagate it.
* typeck2.c (abstract_virtuals_error): Use two loops to emit
abstract virtual functions and virtual functions which need a
final overrider separately.
diff --context --recursive --show-c-function -x CVS -x RCS -x *.o -x *.info* -x *.html* -x *.elc -x *.dvi -x *.orig -x *~ -x version.el egcs-980309.orig/gcc/cp/class.c egcs-980309/gcc/cp/class.c
*** egcs-980309.orig/gcc/cp/class.c Thu Mar 5 09:20:44 1998
--- egcs-980309/gcc/cp/class.c Tue Mar 10 09:52:51 1998
*************** override_one_vtable (binfo, old, t)
*** 2725,2730 ****
--- 2725,2731 ----
fndecl = copy_node (fndecl);
copy_lang_decl (fndecl);
DECL_ABSTRACT_VIRTUAL_P (fndecl) = 1;
+ DECL_NEEDS_FINAL_OVERRIDER_P (fndecl) = 1;
/* Make sure we search for it later. */
if (! CLASSTYPE_ABSTRACT_VIRTUALS (t))
CLASSTYPE_ABSTRACT_VIRTUALS (t) = error_mark_node;
diff --context --recursive --show-c-function -x CVS -x RCS -x *.o -x *.info* -x *.html* -x *.elc -x *.dvi -x *.orig -x *~ -x version.el egcs-980309.orig/gcc/cp/cp-tree.h egcs-980309/gcc/cp/cp-tree.h
*** egcs-980309.orig/gcc/cp/cp-tree.h Thu Mar 5 09:20:44 1998
--- egcs-980309/gcc/cp/cp-tree.h Tue Mar 10 08:38:26 1998
*************** struct lang_decl_flags
*** 969,975 ****
unsigned declared_inline : 1;
unsigned not_really_extern : 1;
unsigned comdat : 1;
! unsigned dummy : 4;
tree access;
tree context;
--- 969,976 ----
unsigned declared_inline : 1;
unsigned not_really_extern : 1;
unsigned comdat : 1;
! unsigned needs_final_overrider : 1;
! unsigned dummy : 3;
tree access;
tree context;
*************** struct lang_decl
*** 1075,1080 ****
--- 1076,1085 ----
/* Nonzero for FUNCTION_DECL means that this member function
exists as part of an abstract class's interface. */
#define DECL_ABSTRACT_VIRTUAL_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.abstract_virtual)
+
+ /* Nonzero for FUNCTION_DECL means that this member function
+ must be overridden by derived classes. */
+ #define DECL_NEEDS_FINAL_OVERRIDER_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.needs_final_overrider)
/* Nonzero if allocated on permanent_obstack. */
#define LANG_DECL_PERMANENT(LANGDECL) ((LANGDECL)->decl_flags.permanent_attr)
diff --context --recursive --show-c-function -x CVS -x RCS -x *.o -x *.info* -x *.html* -x *.elc -x *.dvi -x *.orig -x *~ -x version.el egcs-980309.orig/gcc/cp/decl.c egcs-980309/gcc/cp/decl.c
*** egcs-980309.orig/gcc/cp/decl.c Thu Mar 5 09:20:45 1998
--- egcs-980309/gcc/cp/decl.c Tue Mar 10 08:45:37 1998
*************** duplicate_decls (newdecl, olddecl)
*** 2740,2745 ****
--- 2740,2746 ----
DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
DECL_ABSTRACT_VIRTUAL_P (newdecl) |= DECL_ABSTRACT_VIRTUAL_P (olddecl);
DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl);
+ DECL_NEEDS_FINAL_OVERRIDER_P (newdecl) |= DECL_NEEDS_FINAL_OVERRIDER_P (olddecl);
}
/* Deal with C++: must preserve virtual function table size. */
diff --context --recursive --show-c-function -x CVS -x RCS -x *.o -x *.info* -x *.html* -x *.elc -x *.dvi -x *.orig -x *~ -x version.el egcs-980309.orig/gcc/cp/typeck2.c egcs-980309/gcc/cp/typeck2.c
*** egcs-980309.orig/gcc/cp/typeck2.c Thu Mar 5 09:20:56 1998
--- egcs-980309/gcc/cp/typeck2.c Tue Mar 10 10:39:37 1998
*************** abstract_virtuals_error (decl, type)
*** 130,135 ****
--- 130,152 ----
tree type;
{
tree u = CLASSTYPE_ABSTRACT_VIRTUALS (type);
+ unsigned int no_abstract_virtuals, no_final_overriders;
+ tree tu;
+
+ /* Count how many abstract methods need to be defined. */
+ for (no_abstract_virtuals = 0, tu = u; tu; tu = TREE_CHAIN (tu))
+ {
+ if (DECL_ABSTRACT_VIRTUAL_P (TREE_VALUE (tu))
+ && ! DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
+ ++no_abstract_virtuals;
+ }
+
+ /* Count how many virtual methods need a final overrider. */
+ for (no_final_overriders = 0, tu = u; tu; tu = TREE_CHAIN (tu))
+ {
+ if (DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
+ ++no_final_overriders;
+ }
if (decl)
{
*************** abstract_virtuals_error (decl, type)
*** 151,169 ****
else if (TREE_CODE (decl) == FUNCTION_DECL)
cp_error ("invalid return type for function `%#D'", decl);
}
! else cp_error ("cannot allocate an object of type `%T'", type);
/* Only go through this once. */
if (TREE_PURPOSE (u) == NULL_TREE)
{
- error (" since the following virtual functions are abstract:");
TREE_PURPOSE (u) = error_mark_node;
! while (u)
{
! cp_error ("\t%#D", TREE_VALUE (u));
! u = TREE_CHAIN (u);
}
}
- else cp_error (" since type `%T' has abstract virtual functions", type);
}
/* Print an error message for invalid use of a signature type.
--- 168,219 ----
else if (TREE_CODE (decl) == FUNCTION_DECL)
cp_error ("invalid return type for function `%#D'", decl);
}
! else
! cp_error ("cannot allocate an object of type `%T'", type);
!
/* Only go through this once. */
if (TREE_PURPOSE (u) == NULL_TREE)
{
TREE_PURPOSE (u) = error_mark_node;
!
! if (no_abstract_virtuals > 0)
! error (" since the following virtual functions are abstract:");
! tu = u;
! while (tu)
! {
! if (DECL_ABSTRACT_VIRTUAL_P (TREE_VALUE (tu))
! && ! DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
! cp_error ("\t%#D", TREE_VALUE (tu));
! tu = TREE_CHAIN (tu);
! }
!
! if (no_final_overriders > 0)
! {
! if (no_abstract_virtuals > 0)
! error (" and the following virtual functions need a final overrider:");
! else
! error (" since the following virtual functions need a final overrider:");
! }
! tu = u;
! while (tu)
! {
! if (DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
! cp_error ("\t%#D", TREE_VALUE (tu));
! tu = TREE_CHAIN (tu);
! }
! }
! else
! {
! if (no_abstract_virtuals > 0)
{
! if (no_final_overriders > 0)
! cp_error (" since type `%T' has abstract virtual functions and must override virtual functions", type);
! else
! cp_error (" since type `%T' has abstract virtual functions", type);
}
+ else
+ cp_error (" since type `%T' must override virtual functions", type);
}
}
/* Print an error message for invalid use of a signature type.
More information about the Gcc-bugs
mailing list