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); +}