re PR c++/11750 (class scope using-declaration lookup not implemented)
authorFabien Chêne <fabien@gcc.gnu.org>
Wed, 14 Nov 2012 20:12:47 +0000 (21:12 +0100)
committerFabien Chêne <fabien@gcc.gnu.org>
Wed, 14 Nov 2012 20:12:47 +0000 (21:12 +0100)
gcc/testsuite/ChangeLog

2012-11-14  Fabien Chêne  <fabien@gcc.gnu.org>

PR c++/11750
* g++.dg/inherit/vitual9.C: New.

gcc/cp/ChangeLog

2012-11-14  Fabien Chêne  <fabien@gcc.gnu.org>

PR c++/11750
* call.c (build_new_method_call_1): Check that the instance type
and the function context are the same before setting the flag
LOOKUP_NONVIRTUAL.

From-SVN: r193504

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

index 8d12568..fc53518 100644 (file)
@@ -1,3 +1,10 @@
+2012-11-14  Fabien Chêne  <fabien@gcc.gnu.org>
+
+       PR c++/11750
+       * call.c (build_new_method_call_1): Check that the instance type
+       and the function context are the same before setting the flag
+       LOOKUP_NONVIRTUAL.
+
 2012-11-13  Sriraman Tallam  <tmsriram@google.com>
 
        * class.c (mark_versions_used): Remove.
index bbeea85..77bd288 100644 (file)
@@ -7652,9 +7652,15 @@ 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.  */
+             /* Optimize away vtable lookup if we know that this
+                function can't be overridden.  We need to check if
+                the context and the instance type are the same,
+                actually FN might be defined in a different class
+                type because of a using-declaration. In this case, we
+                do not want to perform a non-virtual call.  */
              if (DECL_VINDEX (fn) && ! (flags & LOOKUP_NONVIRTUAL)
+                 && same_type_ignoring_top_level_qualifiers_p
+                 (DECL_CONTEXT (fn), TREE_TYPE (instance))
                  && resolves_to_fixed_type_p (instance, 0))
                flags |= LOOKUP_NONVIRTUAL;
               if (explicit_targs)
index fec239c..23424c5 100644 (file)
@@ -1,3 +1,10 @@
+2012-11-14  Fabien Chêne  <fabien@gcc.gnu.org>
+
+       PR c++/11750
+       * call.c (build_new_method_call_1): Check that the instance type
+       and the function context are the same before setting the flag
+       LOOKUP_NONVIRTUAL.
+
 2012-11-13  Sriraman Tallam  <tmsriram@google.com>
 
        * testsuite/g++.dg/mv4.C: Add require ifunc. Change error message.
diff --git a/gcc/testsuite/g++.dg/inherit/virtual9.C b/gcc/testsuite/g++.dg/inherit/virtual9.C
new file mode 100644 (file)
index 0000000..0334264
--- /dev/null
@@ -0,0 +1,44 @@
+// { dg-do run }
+// PR c++/11750
+
+struct A
+{
+  virtual void f() const { __builtin_abort(); }
+  virtual void g() {}
+};
+
+struct B : virtual A
+{
+  virtual void f() const {}
+  virtual void g() { __builtin_abort(); }
+};
+
+struct C : B, virtual A
+{
+  using A::f;
+  using A::g;
+};
+
+int main()
+{
+  C c;
+  c.f(); // call B::f
+
+  C c2;
+  c2.C::g(); // call A::g
+
+  C* c3 = &c;
+  c3->f(); // call B::f
+
+  C& c4 = c;
+  c4.f(); // call B::f
+
+  C const* c5 = &c;
+  c5->f(); // call B::f
+
+  C** c6 = &c3;
+  (*c6)->f(); // call B::f
+
+  C const& c7 = c;
+  c7.f(); // call B::f
+}