Hi! push_local_binding/push_overloaded_decl* sometimes inserts OVERLOADs into the lvl->names chain, and for both OVERLOADs and decls from using directive it also wraps them into TREE_LIST. The following patch teaches the spelling check hints processing to handle those, otherwise we ICE in each of the 3 cases in the testcase on using DECL_NAME on TREE_LIST.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2016-09-13 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 13:47:16.000000000 +0200 +++ gcc/cp/name-lookup.c 2016-09-13 13:53:34.874892924 +0200 @@ -4707,6 +4707,14 @@ consider_binding_level (tree name, best_ 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 use bindings from implicitly declared functions, as they were likely misspellings themselves. */ if (TREE_TYPE (t) == error_mark_node) --- gcc/testsuite/g++.dg/lookup/pr77549.C.jj 2016-09-13 14:10:04.569743214 +0200 +++ gcc/testsuite/g++.dg/lookup/pr77549.C 2016-09-13 14:08:57.000000000 +0200 @@ -0,0 +1,48 @@ +// 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 } Jakub