Commit b9f673eb by Jason Merrill Committed by Jason Merrill

re PR c++/35109 (ICE in lookup_name_real, at cp/name-lookup.c:4056)

        PR c++/35109
        * name-lookup.c (lookup_name_real): Keep looking past a hidden
        binding.

Co-Authored-By: Steve Ellcey <sje@cup.hp.com>

From-SVN: r143320
parent 38a5aa4a
2009-01-12 Jason Merrill <jason@redhat.com>
Steve Ellcey <sje@cup.hp.com>
PR c++/35109
* name-lookup.c (lookup_name_real): Keep looking past a hidden
binding.
2009-01-12 Dodji Seketeli <dodji@redhat.com> 2009-01-12 Dodji Seketeli <dodji@redhat.com>
PR c++/36019 PR c++/36019
......
...@@ -4149,16 +4149,25 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p, ...@@ -4149,16 +4149,25 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
{ {
if (hidden_name_p (binding)) if (hidden_name_p (binding))
{ {
/* A non namespace-scope binding can only be hidden if /* A non namespace-scope binding can only be hidden in the
we are in a local class, due to friend declarations. presence of a local class, due to friend declarations.
In particular, consider: In particular, consider:
struct C;
void f() { void f() {
struct A { struct A {
friend struct B; friend struct B;
void g() { B* b; } // error: B is hidden friend struct C;
void g() {
B* b; // error: B is hidden
C* c; // OK, finds ::C
} }
};
B *b; // error: B is hidden
C *c; // OK, finds ::C
struct B {}; struct B {};
B *bb; // OK
} }
The standard says that "B" is a local class in "f" The standard says that "B" is a local class in "f"
...@@ -4174,21 +4183,19 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p, ...@@ -4174,21 +4183,19 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
the name specified is an unqualified name, a prior the name specified is an unqualified name, a prior
declaration is looked up without considering scopes declaration is looked up without considering scopes
that are outside the innermost enclosing non-class that are outside the innermost enclosing non-class
scope. For a friend class declaration, if there is no scope. For a friend function declaration, if there is
prior declaration, the class that is specified no prior declaration, the program is ill-formed. For a
belongs to the innermost enclosing non-class scope, friend class declaration, if there is no prior
but if it is subsequently referenced, its name is not declaration, the class that is specified belongs to the
found by name lookup until a matching declaration is innermost enclosing non-class scope, but if it is
provided in the innermost enclosing nonclass scope. subsequently referenced, its name is not found by name
lookup until a matching declaration is provided in the
innermost enclosing nonclass scope.
So just keep looking for a non-hidden binding.
*/ */
gcc_assert (current_class_type && gcc_assert (TREE_CODE (binding) == TYPE_DECL);
LOCAL_CLASS_P (current_class_type)); continue;
/* This binding comes from a friend declaration in the local
class. The standard (11.4.8) states that the lookup can
only succeed if there is a non-hidden declaration in the
current scope, which is not the case here. */
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
} }
val = binding; val = binding;
break; break;
......
2009-01-12 Jason Merrill <jason@redhat.com>
PR c++/35109
* g++.dg/lookup/friend11.C: Remove expected error.
* g++.dg/lookup/friend14.C: New test.
* g++.dg/lookup/friend15.C: New test.
2009-01-12 Dodji Seketeli <dodji@redhat.com> 2009-01-12 Dodji Seketeli <dodji@redhat.com>
PR c++/36019 PR c++/36019
...@@ -15,6 +22,7 @@ ...@@ -15,6 +22,7 @@
2009-01-12 Jason Merrill <jason@redhat.com> 2009-01-12 Jason Merrill <jason@redhat.com>
PR c++/31488
* g++.dg/other/vararg-3.C: New test. * g++.dg/other/vararg-3.C: New test.
2009-01-12 Daniel Jacobowitz <dan@codesourcery.com> 2009-01-12 Daniel Jacobowitz <dan@codesourcery.com>
......
...@@ -3,12 +3,11 @@ ...@@ -3,12 +3,11 @@
/* { dg-do "compile" } */ /* { dg-do "compile" } */
// This is invalid: QGList must only be looked up in count.
class QGList; class QGList;
unsigned count() { unsigned count() {
class QGListIterator { class QGListIterator {
friend class QGList; friend class QGList;
QGListIterator( const QGList & ); /* { dg-error "expected|with no type" } */ QGListIterator( const QGList & ); // OK, finds ::QGList.
}; };
return 0; return 0;
} }
......
// PR c++/35109
struct C;
void f() {
struct A {
friend struct B;
friend struct C;
void g()
{
B *b; // { dg-error "not declared" }
C* c; // OK, finds ::C
}
};
C *c; // OK, finds ::C
struct B {};
B *b; // OK, now it isn't hidden
}
// Origin: PR c++/35109
// { dg-do compile }
void foo()
{
struct A
{
friend class B;
};
B::B() {} // { dg-error "has not been declared" }
// { dg-error "expected" "expected" { target *-*-* } 10 }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment