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]

Re: This is actually a (was: Re:) Patch for better diagnostic


Jason, how about the patch? In the meantime I `optimized' it a little
bit in order to terminate the two new for loops in
abstract_virtuals_error as soon as we know what to complain about,
instead of running until the list's end.

Sat Mar 14 15:23:23 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 -rup -x CVS -x *.o -x *.info* -x *.html* -x *.elc -x *.dvi -x *.orig -x *~ -x version.el egcs-980313.orig/gcc/cp/class.c egcs-980313/gcc/cp/class.c
--- egcs-980313.orig/gcc/cp/class.c	Thu Mar  5 09:20:44 1998
+++ egcs-980313/gcc/cp/class.c	Sat Mar 14 15:18:57 1998
@@ -2725,6 +2725,7 @@ override_one_vtable (binfo, old, t)
 	    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 -rup -x CVS -x *.o -x *.info* -x *.html* -x *.elc -x *.dvi -x *.orig -x *~ -x version.el egcs-980313.orig/gcc/cp/cp-tree.h egcs-980313/gcc/cp/cp-tree.h
--- egcs-980313.orig/gcc/cp/cp-tree.h	Thu Mar  5 09:20:44 1998
+++ egcs-980313/gcc/cp/cp-tree.h	Sat Mar 14 15:18:57 1998
@@ -969,7 +969,8 @@ struct lang_decl_flags
   unsigned declared_inline : 1;
   unsigned not_really_extern : 1;
   unsigned comdat : 1;
-  unsigned dummy : 4;
+  unsigned needs_final_overrider : 1;
+  unsigned dummy : 3;
 
   tree access;
   tree context;
@@ -1075,6 +1076,10 @@ struct lang_decl
 /* 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 -rup -x CVS -x *.o -x *.info* -x *.html* -x *.elc -x *.dvi -x *.orig -x *~ -x version.el egcs-980313.orig/gcc/cp/decl.c egcs-980313/gcc/cp/decl.c
--- egcs-980313.orig/gcc/cp/decl.c	Thu Mar  5 09:20:45 1998
+++ egcs-980313/gcc/cp/decl.c	Sat Mar 14 15:18:57 1998
@@ -2740,6 +2740,7 @@ duplicate_decls (newdecl, olddecl)
       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 -rup -x CVS -x *.o -x *.info* -x *.html* -x *.elc -x *.dvi -x *.orig -x *~ -x version.el egcs-980313.orig/gcc/cp/typeck2.c egcs-980313/gcc/cp/typeck2.c
--- egcs-980313.orig/gcc/cp/typeck2.c	Thu Mar  5 09:20:56 1998
+++ egcs-980313/gcc/cp/typeck2.c	Sat Mar 14 15:20:58 1998
@@ -130,6 +130,29 @@ abstract_virtuals_error (decl, type)
      tree type;
 {
   tree u = CLASSTYPE_ABSTRACT_VIRTUALS (type);
+  int has_abstract_virtuals, needs_final_overriders;
+  tree tu;
+
+  /* Count how many abstract methods need to be defined.  */
+  for (has_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)))
+	{
+	  has_abstract_virtuals = 1;
+	  break;
+	}
+    }
+
+  /* Count how many virtual methods need a final overrider.  */
+  for (needs_final_overriders = 0, tu = u; tu; tu = TREE_CHAIN (tu))
+    {
+      if (DECL_NEEDS_FINAL_OVERRIDER_P (TREE_VALUE (tu)))
+	{
+	  needs_final_overriders = 1;
+	  break;
+	}
+    }
 
   if (decl)
     {
@@ -151,19 +174,52 @@ abstract_virtuals_error (decl, type)
       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);
+  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)
+
+      if (has_abstract_virtuals)
+	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 (needs_final_overriders)
+	{
+	  if (has_abstract_virtuals)
+	    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 (has_abstract_virtuals)
 	{
-	  cp_error ("\t%#D", TREE_VALUE (u));
-	  u = TREE_CHAIN (u);
+	  if (needs_final_overriders)
+	    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);
     }
-  else cp_error ("  since type `%T' has abstract 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]