diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2019-05-21 22:26:10 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2019-05-21 22:26:10 +0000 |
commit | f2432de6cd0fd5754c2f526e27bc82911d5b8750 (patch) | |
tree | a16e848df8cea09277f3c0f2287ab54f150824f8 /gcc | |
parent | 34d878c7bc86d42fd973ad82ed76759ad423ed88 (diff) | |
download | gcc-f2432de6cd0fd5754c2f526e27bc82911d5b8750.zip gcc-f2432de6cd0fd5754c2f526e27bc82911d5b8750.tar.gz gcc-f2432de6cd0fd5754c2f526e27bc82911d5b8750.tar.bz2 |
re PR c++/67184 (Missed optimization with C++11 final specifier)
/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.
From-SVN: r271490
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/call.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/final3.C | 28 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/final4.C | 16 |
5 files changed, 60 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 972bc36..e26cb98 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +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. + 2019-05-21 Nathan Sidwell <nathan@acm.org> * name-lookup.c (do_nonmember_using_decl): Drop INSERT_P diff --git a/gcc/cp/call.c b/gcc/cp/call.c index e160dd1..1e16785 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 2a4cd7f..8c3e8a4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +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. + 2019-05-21 Marek Polacek <polacek@redhat.com> 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 0000000..a49dc22 --- /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 0000000..867ef38 --- /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" } } |