diff options
author | paolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-05-03 14:28:46 +0000 |
---|---|---|
committer | paolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-05-03 14:28:46 +0000 |
commit | 6b45067f95c84354308bc05b3074c5ec16e2149b (patch) | |
tree | 15f1bda4374b20c465ed4e02d97a90f4645632fe /gcc | |
parent | 1ef2db757f69a5e31d5bd68768b71f6d12262ab5 (diff) | |
download | gcc-6b45067f95c84354308bc05b3074c5ec16e2149b.tar.gz |
/cp
2012-05-03 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/53186
* call.c (build_over_call): Handle final member functions
and class types.
(build_new_method_call_1): Do not handle here.
/testsuite
2012-05-03 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/53186
* g++.dg/other/final2.C: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@187097 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/call.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/other/final2.C | 27 |
4 files changed, 46 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6b0e57cedb5..46d8b89a0ed 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2012-05-03 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/53186 + * call.c (build_over_call): Handle final member functions + and class types. + (build_new_method_call_1): Do not handle here. + 2012-05-02 Richard Guenther <rguenther@suse.de> * decl.c (grokdeclarator): Properly check for sizes that diff --git a/gcc/cp/call.c b/gcc/cp/call.c index e072891f927..8ae4afe4445 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6550,6 +6550,12 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) return error_mark_node; } + /* 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)))) + flags |= LOOKUP_NONVIRTUAL; + /* [class.mfct.nonstatic]: If a nonstatic member function of a class X is called for an object that is not of type X, or of a type derived from X, the behavior is undefined. @@ -7418,8 +7424,7 @@ build_new_method_call_1 (tree instance, tree fns, VEC(tree,gc) **args, /* Optimize away vtable lookup if we know that this function can't be overridden. */ if (DECL_VINDEX (fn) && ! (flags & LOOKUP_NONVIRTUAL) - && (resolves_to_fixed_type_p (instance, 0) - || DECL_FINAL_P (fn) || CLASSTYPE_FINAL (basetype))) + && resolves_to_fixed_type_p (instance, 0)) flags |= LOOKUP_NONVIRTUAL; if (explicit_targs) flags |= LOOKUP_EXPLICIT_TMPL_ARGS; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c35bd8523ab..1378ff45d9c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-05-03 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/53186 + * g++.dg/other/final2.C: New. + 2012-05-03 Richard Guenther <rguenther@suse.de> * gcc.dg/tree-ssa/ssa-pre-27.c: Remove XFAIL. diff --git a/gcc/testsuite/g++.dg/other/final2.C b/gcc/testsuite/g++.dg/other/final2.C new file mode 100644 index 00000000000..a07562299d6 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/final2.C @@ -0,0 +1,27 @@ +// PR c++/53186 +// { dg-options "-fdump-tree-original -std=c++11" } + +struct F1 +{ + virtual void operator()() final; + virtual operator int() final; + virtual int operator++() final; +}; + +struct F2 final +{ + virtual void operator()(); + virtual operator int(); + virtual int operator++(); +}; + +void fooF1(F1& a) { a(); int m = a; ++a; } +void fooF2(F2& a) { a(); int m = a; ++a; } + +// { dg-final { scan-tree-dump-times "F1::operator\\(\\)" 1 "original" } } +// { dg-final { scan-tree-dump-times "F1::operator int" 1 "original" } } +// { dg-final { scan-tree-dump-times "F1::operator\\+\\+" 1 "original" } } +// { dg-final { scan-tree-dump-times "F2::operator\\(\\)" 1 "original" } } +// { dg-final { scan-tree-dump-times "F2::operator int" 1 "original" } } +// { dg-final { scan-tree-dump-times "F2::operator\\+\\+" 1 "original" } } +// { dg-final { cleanup-tree-dump "original" } } |