re PR c++/11750 (class scope using-declaration lookup not implemented)

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
This commit is contained in:
Fabien Chêne 2012-11-14 21:12:47 +01:00
parent ccd025e14c
commit 7628dc541e
4 changed files with 66 additions and 2 deletions

View 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.

View 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)

View 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.

View file

@ -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
}