summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2012-05-03 14:28:46 +0000
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>2012-05-03 14:28:46 +0000
commit6b45067f95c84354308bc05b3074c5ec16e2149b (patch)
tree15f1bda4374b20c465ed4e02d97a90f4645632fe /gcc
parent1ef2db757f69a5e31d5bd68768b71f6d12262ab5 (diff)
downloadgcc-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/ChangeLog7
-rw-r--r--gcc/cp/call.c9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/other/final2.C27
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" } }