call.c (build_new_method_call_1): Use non-virtual lookup for final virtual functions.
authorRoberto Agostino Vitillo <ravitillo@lbl.gov>
Tue, 20 Sep 2011 19:25:24 +0000 (19:25 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 20 Sep 2011 19:25:24 +0000 (15:25 -0400)
* call.c (build_new_method_call_1): Use non-virtual lookup
for final virtual functions.

From-SVN: r179014

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/other/final1.C [new file with mode: 0644]

index a6de5fae3c7e1210aeb7deaae99337dbe0b50234..b85e16c3eb02f0b9bb1ffa5acdcc955a5b39ab06 100644 (file)
@@ -1,3 +1,8 @@
+2011-09-20 Roberto Agostino Vitillo <ravitillo@lbl.gov>
+
+       * call.c (build_new_method_call_1): Use non-virtual lookup
+       for final virtual functions.
+
 2011-09-16  Jason Merrill  <jason@redhat.com>
 
        PR c++/50424
index bdbede7fbe646860592c9327d3075981e0dcaf87..873b48b32b537a334b382e4505894d63848652c1 100644 (file)
@@ -7282,8 +7282,11 @@ build_new_method_call_1 (tree instance, tree fns, VEC(tree,gc) **args,
            }
          else
            {
+             /* 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))
+                 && (resolves_to_fixed_type_p (instance, 0)
+                     || DECL_FINAL_P (fn) || CLASSTYPE_FINAL (basetype)))
                flags |= LOOKUP_NONVIRTUAL;
               if (explicit_targs)
                 flags |= LOOKUP_EXPLICIT_TMPL_ARGS;
index a5b35772c16dc5e87295e2c5ccc47f5cd49acc4b..bd543b07811ef3751f03ef7fe3b62b4282daa9a5 100644 (file)
@@ -1,3 +1,7 @@
+2011-09-20 Roberto Agostino Vitillo <ravitillo@lbl.gov>
+
+       * g++.dg/other/final1.C: new test
+
 2011-09-20  Ira Rosen  <ira.rosen@linaro.org>
 
        * g++.dg/vect/slp-pr50413.cc: Don't run the test.  Remove main ()
diff --git a/gcc/testsuite/g++.dg/other/final1.C b/gcc/testsuite/g++.dg/other/final1.C
new file mode 100644 (file)
index 0000000..ffb30c3
--- /dev/null
@@ -0,0 +1,26 @@
+/* Verify that final methods are devirtualized */
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-original -std=c++0x"  } */
+
+struct A final
+{
+  virtual void foo ()
+  {
+  }
+};
+
+struct B
+{
+  virtual void foo () final
+  {
+  }
+};
+
+void fun(A* a, B* b)
+{
+  a->foo();
+  b->foo();
+}
+
+/* { dg-final { scan-tree-dump-times "A::foo" 2 "original"  } } */
+/* { dg-final { scan-tree-dump-times "B::foo" 2 "original"  } } */