This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix ICE in C++ lookup_name_fuzzy (PR c++/77549, take 2)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: David Malcolm <dmalcolm at redhat dot com>, gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 14 Sep 2016 09:43:02 +0200
- Subject: [C++ PATCH] Fix ICE in C++ lookup_name_fuzzy (PR c++/77549, take 2)
- Authentication-results: sourceware.org; auth=none
- References: <20160913192618.GL7282@tucnak.redhat.com> <CADzB+2nPGHzCVUsL8g3hqrppZtqi-egcDOFg_jcCQK_J+_MB+A@mail.gmail.com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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