On Tue, Sep 13, 2016 at 11:46:52PM -0400, Jason Merrill wrote:
> On Tue, Sep 13, 2016 at 3:26 PM, Jakub Jelinek <ja...@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  <ja...@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

Reply via email to