adjust_result_of_qualified_name_lookup() may erroneously clobber the BASELINK_BINFO of its DECL argument if the BINFO_TYPE of DECL is an ambiguous base of the qualifying scope that's used to refer to DECL. But as the comment in the function suggests, this base ambiguity is not necessarily a problem since DECL may later get resolved to a static member function.
This patch makes updating the BASELINK_BINFO of DECL conditional on the validity of the return value of the 2nd call to lookup_base as well as on the 1st call. Not sure if we should still update BASELINK_ACCESS_BINFO if the 2nd call fails, but I suppose it shouldn't hurt. I can't come up with a test case where this would make a difference. Bootstrap + regtest in progress on x86_64-pc-linux-gnu, also will test against Boost, does this look OK to commit if testing succeeds? gcc/cp/ChangeLog: PR c++/70205 * search.c (adjust_result_of_qualified_name_lookup): Don't update the BASELINK_BINFO of DECL if the second call to lookup_base fails. gcc/testsuite/ChangeLog: PR c++/70205 * g++.dg/lookup/pr70205.C: New test. --- gcc/cp/search.c | 4 +++- gcc/testsuite/g++.dg/lookup/pr70205.C | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/lookup/pr70205.C diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 7924611..503e34b 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1751,9 +1751,11 @@ adjust_result_of_qualified_name_lookup (tree decl, if (base && base != error_mark_node) { BASELINK_ACCESS_BINFO (decl) = base; - BASELINK_BINFO (decl) + tree decl_binfo = lookup_base (base, BINFO_TYPE (BASELINK_BINFO (decl)), ba_unique, NULL, tf_none); + if (decl_binfo && decl_binfo != error_mark_node) + BASELINK_BINFO (decl) = decl_binfo; } } diff --git a/gcc/testsuite/g++.dg/lookup/pr70205.C b/gcc/testsuite/g++.dg/lookup/pr70205.C new file mode 100644 index 0000000..3bda7fb --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/pr70205.C @@ -0,0 +1,11 @@ +// PR c++/70205 + +struct A +{ +protected: + static void f (); +}; +struct B : A { }; +struct C : A { }; +struct D : C, B { void a () { D::f (); } }; +struct E : D { void b () { D::f (); } }; -- 2.8.0.rc1.12.gfce6d53