Message ID | 20160914074302.GM7282@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
OK, thanks. On Wed, Sep 14, 2016 at 3:43 AM, Jakub Jelinek <jakub@redhat.com> wrote: > 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
--- 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 }