From: Paolo Carlini Date: Tue, 21 May 2019 22:26:10 +0000 (+0000) Subject: re PR c++/67184 (Missed optimization with C++11 final specifier) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f2432de6cd0fd5754c2f526e27bc82911d5b8750;p=gcc.git re PR c++/67184 (Missed optimization with C++11 final specifier) /cp 2019-05-21 Paolo Carlini 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 PR c++/67184 PR c++/69445 * g++.dg/other/final3.C: New. * g++.dg/other/final4.C: Likewise. * g++.dg/other/final5.C: Likewise. From-SVN: r271490 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 972bc36c0be..e26cb9856ff 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-05-21 Paolo Carlini + + PR c++/67184 + PR c++/69445 + * call.c (build_over_call): Devirtualize when the final overrider + comes from the base. + 2019-05-21 Nathan Sidwell * name-lookup.c (do_nonmember_using_decl): Drop INSERT_P diff --git a/gcc/cp/call.c b/gcc/cp/call.c index e160dd160ea..1e167851872 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -8244,7 +8244,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) /* See if the function member or the whole class type is declared final and the call can be devirtualized. */ if (DECL_FINAL_P (fn) - || CLASSTYPE_FINAL (TYPE_METHOD_BASETYPE (TREE_TYPE (fn)))) + || CLASSTYPE_FINAL (TREE_TYPE (argtype))) flags |= LOOKUP_NONVIRTUAL; /* [class.mfct.nonstatic]: If a nonstatic member function of a class diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2a4cd7fe471..8c3e8a4488a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-05-21 Paolo Carlini + + PR c++/67184 + PR c++/69445 + * g++.dg/other/final3.C: New. + * g++.dg/other/final4.C: Likewise. + * g++.dg/other/final5.C: Likewise. + 2019-05-21 Marek Polacek DR 1940 - static_assert in anonymous unions. diff --git a/gcc/testsuite/g++.dg/other/final3.C b/gcc/testsuite/g++.dg/other/final3.C new file mode 100644 index 00000000000..a49dc22a0d2 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/final3.C @@ -0,0 +1,28 @@ +// PR c++/67184 +// { dg-do compile { target c++11 } } +// { dg-options "-fdump-tree-original" } + +struct V { + virtual void foo(); +}; + +struct wV final : V { +}; + +struct oV final : V { + void foo(); +}; + +void call(wV& x) +{ + x.foo(); + x.V::foo(); +} + +void call(oV& x) +{ + x.foo(); + x.V::foo(); +} + +// { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 0 "original" } } diff --git a/gcc/testsuite/g++.dg/other/final4.C b/gcc/testsuite/g++.dg/other/final4.C new file mode 100644 index 00000000000..867ef3830e7 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/final4.C @@ -0,0 +1,16 @@ +// PR c++/67184 +// { dg-do compile { target c++11 } } +// { dg-options "-fdump-tree-original" } + +struct B +{ + virtual void operator()(); + virtual operator int(); + virtual int operator++(); +}; + +struct D final : B { }; + +void foo(D& d) { d(); int t = d; ++d; } + +// { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 0 "original" } }