[C++] vfunc overrider simplification
diff mbox series

Message ID 2a3d24b1-a0ee-4e0c-45e5-04b0bd83dc03@acm.org
State New
Headers show
Series
  • [C++] vfunc overrider simplification
Related show

Commit Message

Nathan Sidwell Aug. 23, 2019, 7:24 p.m. UTC
In fixing a vfunc override bug on the modules branch, I noticed that 
check_for_override can simply check IDENTIFIER_VIRTUAL_P -- the dtor 
identifier and those for conversion operators will have it set 
correctly.  (there a multiple conversion operator identifiers, but we 
can only be overriding the one with the same return type, so that's fine.)

While there I moved the DECL_OVERRIDE_P check up and avoid needing a 
bool flag.

committing to trunk.

nathan

Comments

Nathan Sidwell Aug. 24, 2019, 10:43 p.m. UTC | #1
On 8/23/19 3:24 PM, Nathan Sidwell wrote:
> In fixing a vfunc override bug on the modules branch, I noticed that 
> check_for_override can simply check IDENTIFIER_VIRTUAL_P -- the dtor 
> identifier and those for conversion operators will have it set 
> correctly.  (there a multiple conversion operator identifiers, but we 
> can only be overriding the one with the same return type, so that's fine.)

that turns out to be untrue -- the conversion operator table 
distinguishes between different typedefs of the same type.  This patch 
restores the DECL_CONV_FN_P test.

Applying to trunk.

nathan
Jason Merrill Aug. 25, 2019, 6:35 p.m. UTC | #2
On Sat, Aug 24, 2019 at 6:43 PM Nathan Sidwell <nathan@acm.org> wrote:

> On 8/23/19 3:24 PM, Nathan Sidwell wrote:
> > In fixing a vfunc override bug on the modules branch, I noticed that
> > check_for_override can simply check IDENTIFIER_VIRTUAL_P -- the dtor
> > identifier and those for conversion operators will have it set
> > correctly.  (there a multiple conversion operator identifiers, but we
> > can only be overriding the one with the same return type, so that's
> fine.)
>
> that turns out to be untrue -- the conversion operator table
> distinguishes between different typedefs of the same type.


Hmm, that seems like a bug.

Jason
Nathan Sidwell Aug. 26, 2019, 11:03 a.m. UTC | #3
On 8/25/19 2:35 PM, Jason Merrill wrote:
> On Sat, Aug 24, 2019 at 6:43 PM Nathan Sidwell <nathan@acm.org 
> <mailto:nathan@acm.org>> wrote:
> 
>     On 8/23/19 3:24 PM, Nathan Sidwell wrote:
>      > In fixing a vfunc override bug on the modules branch, I noticed that
>      > check_for_override can simply check IDENTIFIER_VIRTUAL_P -- the dtor
>      > identifier and those for conversion operators will have it set
>      > correctly.  (there a multiple conversion operator identifiers,
>     but we
>      > can only be overriding the one with the same return type, so
>     that's fine.)
> 
>     that turns out to be untrue -- the conversion operator table
>     distinguishes between different typedefs of the same type.
> 
> 
> Hmm, that seems like a bug.

It is by design.  That way we can propagate the form of the type to the 
function decl.

nathan

Patch
diff mbox series

2019-08-23  Nathan Sidwell  <nathan@acm.org>

	* class.c (check_for_override): Checking IDENTIFIER_VIRTUAL_P is
	sufficient, reorder DECL_OVERRIDE_P check.

Index: gcc/cp/class.c
===================================================================
--- gcc/cp/class.c	(revision 274860)
+++ gcc/cp/class.c	(working copy)
@@ -2803,12 +2803,11 @@  get_basefndecls (tree name, tree t, vec<
 }
 
-/* If this declaration supersedes the declaration of
-   a method declared virtual in the base class, then
-   mark this field as being virtual as well.  */
+/* If this method overrides a virtual method from a base, then mark
+   this member function as being virtual as well.  Do 'final' and
+   'override' checks too.  */
 
 void
 check_for_override (tree decl, tree ctype)
 {
-  bool overrides_found = false;
   if (TREE_CODE (decl) == TEMPLATE_DECL)
     /* In [temp.mem] we have:
@@ -2817,15 +2816,19 @@  check_for_override (tree decl, tree ctyp
 	 override a virtual function from a base class.  */
     return;
-  if ((DECL_DESTRUCTOR_P (decl)
-       || IDENTIFIER_VIRTUAL_P (DECL_NAME (decl))
-       || DECL_CONV_FN_P (decl))
+
+  /* IDENTIFIER_VIRTUAL_P indicates whether the name has ever been
+     used for a vfunc.  That avoids the expensive
+     look_for_overrides call that when we know there's nothing to
+     find.  */
+  if (IDENTIFIER_VIRTUAL_P (DECL_NAME (decl))
       && look_for_overrides (ctype, decl)
+      /* Check staticness after we've checked if we 'override'.  */
       && !DECL_STATIC_FUNCTION_P (decl))
-    /* Set DECL_VINDEX to a value that is neither an INTEGER_CST nor
-       the error_mark_node so that we know it is an overriding
-       function.  */
     {
+      /* Set DECL_VINDEX to a value that is neither an INTEGER_CST nor
+	 the error_mark_node so that we know it is an overriding
+	 function.  */
       DECL_VINDEX (decl) = decl;
-      overrides_found = true;
+
       if (warn_override
 	  && !DECL_OVERRIDE_P (decl)
@@ -2835,10 +2838,16 @@  check_for_override (tree decl, tree ctyp
 		    "%qD can be marked override", decl);
     }
+  else if (DECL_OVERRIDE_P (decl))
+    error ("%q+#D marked %<override%>, but does not override", decl);
 
   if (DECL_VIRTUAL_P (decl))
     {
+      /* Remember this identifier is virtual name.  */
+      IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = true;
+
       if (!DECL_VINDEX (decl))
+	/* It's a new vfunc.  */
 	DECL_VINDEX (decl) = error_mark_node;
-      IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1;
+
       if (DECL_DESTRUCTOR_P (decl))
 	TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
@@ -2846,6 +2855,4 @@  check_for_override (tree decl, tree ctyp
   else if (DECL_FINAL_P (decl))
     error ("%q+#D marked %<final%>, but is not virtual", decl);
-  if (DECL_OVERRIDE_P (decl) && !overrides_found)
-    error ("%q+#D marked %<override%>, but does not override", decl);
 }