This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

This is actually a (was: Re:) Patch for better diagnostic (was: Re: Bug in MI?))


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]