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

--
Nathan Sidwell
2019-08-24  Nathan Sidwell  <nat...@acm.org>

	cp/
	* class.c (check_for_overrides): Conversion operators need
	checking too.

	testsuite/
	* g++.dg/inherit/virtual14.C: New.

Index: cp/class.c
===================================================================
--- cp/class.c	(revision 274902)
+++ cp/class.c	(working copy)
@@ -2817,10 +2817,12 @@ check_for_override (tree decl, tree ctyp
     return;
 
   /* 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))
+     used for a vfunc.  That avoids the expensive look_for_overrides
+     call that when we know there's nothing to find.  As conversion
+     operators for the same type can have distinct identifiers, we
+     cannot optimize those in that way.  */
+  if ((IDENTIFIER_VIRTUAL_P (DECL_NAME (decl))
+       || DECL_CONV_FN_P (decl))
       && look_for_overrides (ctype, decl)
       /* Check staticness after we've checked if we 'override'.  */
       && !DECL_STATIC_FUNCTION_P (decl))
Index: testsuite/g++.dg/inherit/virtual14.C
===================================================================
--- testsuite/g++.dg/inherit/virtual14.C	(nonexistent)
+++ testsuite/g++.dg/inherit/virtual14.C	(working copy)
@@ -0,0 +1,24 @@
+// { dg-do run }
+
+struct base 
+{
+  virtual operator int () { return 0;}
+};
+
+typedef int q;
+
+struct d : base
+{
+  operator q () { return 1; }
+};
+
+int invoke (base *d)
+{
+  return int (*d);
+}
+
+int main ()
+{
+  d d;
+  return !(invoke (&d) == 1);
+}

Reply via email to