diff options
author | Fabien Chêne <fabien@gcc.gnu.org> | 2012-11-14 21:12:47 +0100 |
---|---|---|
committer | Fabien Chêne <fabien@gcc.gnu.org> | 2012-11-14 21:12:47 +0100 |
commit | 7628dc541e7092f0d58de9a3622ce242807cb47d (patch) | |
tree | a138a764fd88db8b06626eb9bfea1e90755b2ede /gcc | |
parent | ccd025e14c48690c37d0321be833a426df31dc16 (diff) | |
download | gcc-7628dc541e7092f0d58de9a3622ce242807cb47d.zip gcc-7628dc541e7092f0d58de9a3622ce242807cb47d.tar.gz gcc-7628dc541e7092f0d58de9a3622ce242807cb47d.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/call.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/inherit/virtual9.C | 44 |
4 files changed, 66 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8d12568..fc5351815 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index bbeea85..77bd288 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fec239c..23424c5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..0334264 --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/virtual9.C @@ -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 +} |