struct V { virtual void foo(); }; struct wV final : V { }; struct oV final : V { void foo(); }; void call(V& x) { x.foo(); } void call(wV& x) { x.foo(); } void call(oV& x) { x.foo(); } # compile with g++ -O3 -std=c++11 gcc 5.1 and 5.2 on x86-64 generate: call(V&): movq (%rdi), %rax jmp *(%rax) call(wV&): movq (%rdi), %rax jmp *(%rax) call(oV&): jmp oV::foo() I would expect call(wV&) to generate the same code as call(oV&). FWIW Clang generates the expected code since about 3.5.
Confirmed. Adding CC.
Related to c++/65143.
(In reply to Paolo Carlini from comment #2) > Related to c++/65143. Yes, lets close this one. *** This bug has been marked as a duplicate of bug 65143 ***
Not a dup, this is a different case.
*** Bug 69445 has been marked as a duplicate of this bug. ***
(In reply to Giovanni Deretta from comment #0) > I would expect call(wV&) to generate the same code as call(oV&). Except of course it should be a direct call to V::foo(), not oV::foo(). As I showed in Bug 69445 the devirtualization does happen when the final overrider is in the derived class: struct Base { virtual void foo() const {}; virtual void bar() const {} }; struct C final : Base { void foo() const { } }; void func(const C & c) { c.foo(); // optimized away c.bar(); } It doesn't happen when the final overrider comes from the base.
Seems doable.
Author: paolo Date: Tue May 21 22:26:10 2019 New Revision: 271490 URL: https://gcc.gnu.org/viewcvs?rev=271490&root=gcc&view=rev Log: /cp 2019-05-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/67184 PR c++/69445 * call.c (build_over_call): Devirtualize when the final overrider comes from the base. /testsuite 2019-05-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/67184 PR c++/69445 * g++.dg/other/final3.C: New. * g++.dg/other/final4.C: Likewise. * g++.dg/other/final5.C: Likewise. Added: trunk/gcc/testsuite/g++.dg/other/final3.C trunk/gcc/testsuite/g++.dg/other/final4.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/testsuite/ChangeLog
Author: paolo Date: Tue May 21 22:26:42 2019 New Revision: 271491 URL: https://gcc.gnu.org/viewcvs?rev=271491&root=gcc&view=rev Log: /cp 2019-05-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/67184 PR c++/69445 * call.c (build_over_call): Devirtualize when the final overrider comes from the base. /testsuite 2019-05-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/67184 PR c++/69445 * g++.dg/other/final3.C: New. * g++.dg/other/final4.C: Likewise. * g++.dg/other/final5.C: Likewise. Added: trunk/gcc/testsuite/g++.dg/other/final5.C
Fixed.
Author: paolo Date: Fri Jun 21 20:46:51 2019 New Revision: 272573 URL: https://gcc.gnu.org/viewcvs?rev=272573&root=gcc&view=rev Log: /cp 2019-06-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/90909 Revert: 2019-05-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/67184 PR c++/69445 * call.c (build_over_call): Devirtualize when the final overrider comes from the base. /testsuite 2019-06-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/90909 Revert: 2019-05-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/67184 PR c++/69445 * g++.dg/other/final3.C: New. * g++.dg/other/final4.C: Likewise. * g++.dg/other/final5.C: Likewise. * g++.dg/other/final6.C: New. Added: trunk/gcc/testsuite/g++.dg/other/final6.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/testsuite/ChangeLog
Author: paolo Date: Fri Jun 21 20:47:40 2019 New Revision: 272574 URL: https://gcc.gnu.org/viewcvs?rev=272574&root=gcc&view=rev Log: /cp 2019-06-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/90909 Revert: 2019-05-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/67184 PR c++/69445 * call.c (build_over_call): Devirtualize when the final overrider comes from the base. /testsuite 2019-06-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/90909 Revert: 2019-05-21 Paolo Carlini <paolo.carlini@oracle.com> PR c++/67184 PR c++/69445 * g++.dg/other/final3.C: New. * g++.dg/other/final4.C: Likewise. * g++.dg/other/final5.C: Likewise. * g++.dg/other/final6.C: New. Removed: trunk/gcc/testsuite/g++.dg/other/final3.C trunk/gcc/testsuite/g++.dg/other/final4.C trunk/gcc/testsuite/g++.dg/other/final5.C
Unfortunately I have to re-open this: the fix, as-is, caused c++/90909.
Let's look a bit more into this (with Jason' help)
With Jason's r272656 remains to be handled what I had as other/final4.C. final.3.C and final5.C are fine, I'm probably going to add those two to the testsuite.
Author: paolo Date: Wed Jun 26 08:51:50 2019 New Revision: 272675 URL: https://gcc.gnu.org/viewcvs?rev=272675&root=gcc&view=rev Log: 2019-06-26 Paolo Carlini <paolo.carlini@oracle.com> PR c++/67184 PR c++/69445 * g++.dg/other/final3.C: New. * g++.dg/other/final5.C: Likewise. Added: trunk/gcc/testsuite/g++.dg/other/final3.C trunk/gcc/testsuite/g++.dg/other/final5.C Modified: trunk/gcc/testsuite/ChangeLog
Author: paolo Date: Fri Jul 5 18:03:05 2019 New Revision: 273147 URL: https://gcc.gnu.org/viewcvs?rev=273147&root=gcc&view=rev Log: /cp 2019-07-05 Paolo Carlini <paolo.carlini@oracle.com> PR c++/67184 (again) PR c++/69445 * call.c (build_over_call): Devirtualize user-defined operators coming from a base too. (build_new_method_call_1): Do not devirtualize here. /testsuite 2019-07-05 Paolo Carlini <paolo.carlini@oracle.com> PR c++/67184 (again) PR c++/69445 * g++.dg/other/final4.C: New. Added: trunk/gcc/testsuite/g++.dg/other/final4.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/testsuite/ChangeLog
Finally should be completely fixed without regressions.
Author: jakub Date: Fri Jul 5 20:51:44 2019 New Revision: 273149 URL: https://gcc.gnu.org/viewcvs?rev=273149&root=gcc&view=rev Log: PR c++/67184 PR c++/69445 * call.c (build_new_method_call_1): Remove set but not used variable binfo. Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c
The releases/gcc-9 branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:30a100abe48cebcdf3d685e856850d4192f05ad9 commit r9-10161-g30a100abe48cebcdf3d685e856850d4192f05ad9 Author: Jakub Jelinek <jakub@redhat.com> Date: Fri Jul 5 22:51:44 2019 +0200 re PR c++/67184 (Missed optimization with C++11 final specifier) PR c++/67184 PR c++/69445 * call.c (build_new_method_call_1): Remove set but not used variable binfo.