diff mbox

Fix PR c++/70205 (ICE on valid call to qualified static member function)

Message ID 1458228688-14054-1-git-send-email-patrick@parcs.ath.cx
State New
Headers show

Commit Message

Patrick Palka March 17, 2016, 3:31 p.m. UTC
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

Comments

Jason Merrill March 17, 2016, 3:48 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

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 (); } };