Index: cp/call.c
===================================================================
--- cp/call.c	(revision 188293)
+++ cp/call.c	(working copy)
@@ -7449,9 +7449,14 @@
 	    }
 	  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 migth 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_p (DECL_CONTEXT (fn), TREE_TYPE (instance))
 		  && resolves_to_fixed_type_p (instance, 0))
 		flags |= LOOKUP_NONVIRTUAL;
               if (explicit_targs)
Index: testsuite/g++.dg/inherit/virtual9.C
===================================================================
--- testsuite/g++.dg/inherit/virtual9.C	(revision 0)
+++ testsuite/g++.dg/inherit/virtual9.C	(revision 0)
@@ -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
+}
