This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH] Fix ICE in C++ lookup_name_fuzzy (PR c++/77549, take 2)


On Tue, Sep 13, 2016 at 11:46:52PM -0400, Jason Merrill wrote:
> On Tue, Sep 13, 2016 at 3:26 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> >    for (tree t = lvl->names; t; t = TREE_CHAIN (t))
> >      {
> > +      /* OVERLOADs or decls from using declaration are wrapped into
> > +        TREE_LIST.  */
> > +      if (TREE_CODE (t) == TREE_LIST)
> > +       {
> > +         t = TREE_VALUE (t);
> > +         t = OVL_CURRENT (t);
> > +       }
> 
> Don't we want the loop increment to take the TREE_CHAIN of the
> TREE_LIST element, rather than its TREE_VALUE?

Oops, thanks for catching this brown paper bag bug.
I've added a testcase that fails with the previous version of the patch
and succeeds now.  Ok for trunk if it passes bootstrap/regtest?
(as the code changes anything only if it would formerly ICE, I'm afraid
it isn't tested by anything but this new testcase)

2016-09-14  Jakub Jelinek  <jakub@redhat.com>

	PR c++/77549
	* name-lookup.c (consider_binding_level): Look through TREE_LIST
	and OVERLOAD.

	* g++.dg/lookup/pr77549.C: New test.

--- gcc/cp/name-lookup.c.jj	2016-09-13 19:06:24.664238422 +0200
+++ gcc/cp/name-lookup.c	2016-09-14 09:33:13.471134995 +0200
@@ -4707,19 +4707,29 @@ consider_binding_level (tree name, best_
 
   for (tree t = lvl->names; t; t = TREE_CHAIN (t))
     {
+      tree d = t;
+
+      /* OVERLOADs or decls from using declaration are wrapped into
+	 TREE_LIST.  */
+      if (TREE_CODE (d) == TREE_LIST)
+	{
+	  d = TREE_VALUE (d);
+	  d = OVL_CURRENT (d);
+	}
+
       /* Don't use bindings from implicitly declared functions,
 	 as they were likely misspellings themselves.  */
-      if (TREE_TYPE (t) == error_mark_node)
+      if (TREE_TYPE (d) == error_mark_node)
 	continue;
 
       /* Skip anticipated decls of builtin functions.  */
-      if (TREE_CODE (t) == FUNCTION_DECL
-	  && DECL_BUILT_IN (t)
-	  && DECL_ANTICIPATED (t))
+      if (TREE_CODE (d) == FUNCTION_DECL
+	  && DECL_BUILT_IN (d)
+	  && DECL_ANTICIPATED (d))
 	continue;
 
-      if (DECL_NAME (t))
-	bm.consider (DECL_NAME (t));
+      if (DECL_NAME (d))
+	bm.consider (DECL_NAME (d));
     }
 }
 
--- gcc/testsuite/g++.dg/lookup/pr77549.C.jj	2016-09-14 09:15:31.135528309 +0200
+++ gcc/testsuite/g++.dg/lookup/pr77549.C	2016-09-14 09:32:05.951981052 +0200
@@ -0,0 +1,76 @@
+// PR c++/77549
+// { dg-do compile }
+
+struct A
+{ 
+  static int x;
+};
+
+void
+f1 ()
+{ 
+  using ::A;
+  x;			// { dg-error "'x' was not declared in this scope" }
+}
+
+namespace N
+{
+  int bar;
+}
+
+void
+f2 ()
+{
+  using N::bar;
+  baz++;		// { dg-error "'baz' was not declared in this scope" }
+}			// { dg-message "note: suggested alternative: 'bar'" "" { target *-*-* } 25 }
+
+int
+bar ()
+{
+  return 0;
+}
+
+namespace M
+{
+  int
+  bar ()
+  {
+    return 0;
+  }
+}
+
+void
+f3 ()
+{
+  using M::bar;
+  baz ();		// { dg-error "'baz' was not declared in this scope" }
+}			// { dg-message "note: suggested alternative: 'bar'" "" { target *-*-* } 47 }
+
+namespace O
+{
+  int
+  foo ()
+  {
+    return 0;
+  }
+}
+
+namespace P
+{
+  int
+  bar ()
+  {
+    return 0;
+  }
+}
+
+void
+f4 ()
+{
+  using O::foo;
+  using P::bar;
+  fooo ();		// { dg-error "'fooo' was not declared in this scope" }
+			// { dg-message "note: suggested alternative: 'foo'" "" { target *-*-* } 73 }
+  baz ();		// { dg-error "'baz' was not declared in this scope" }
+}			// { dg-message "note: suggested alternative: 'bar'" "" { target *-*-* } 75 }


	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]