aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-01-12 20:23:34 -0500
committerJason Merrill <jason@gcc.gnu.org>2009-01-12 20:23:34 -0500
commitb9f673eb35aa687a05466b8532c25d3e56e3e1bd (patch)
tree2e2f7a94f379c6d05b2c37967205e5c492653764 /gcc/cp
parent38a5aa4ae441872f621fa42a737b8c0dbd8184a4 (diff)
downloadgcc-b9f673eb35aa687a05466b8532c25d3e56e3e1bd.zip
gcc-b9f673eb35aa687a05466b8532c25d3e56e3e1bd.tar.gz
gcc-b9f673eb35aa687a05466b8532c25d3e56e3e1bd.tar.bz2
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
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/name-lookup.c43
2 files changed, 32 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 542b71d..7e35ecd 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+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>
PR c++/36019
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 889d9ef..d0f85f9 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4149,16 +4149,25 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
{
if (hidden_name_p (binding))
{
- /* A non namespace-scope binding can only be hidden if
- we are in a local class, due to friend declarations.
+ /* A non namespace-scope binding can only be hidden in the
+ presence of a local class, due to friend declarations.
+
In particular, consider:
+ struct C;
void f() {
struct A {
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 {};
+ B *bb; // OK
}
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,
the name specified is an unqualified name, a prior
declaration is looked up without considering scopes
that are outside the innermost enclosing non-class
- scope. For a friend class declaration, if there is no
- prior declaration, the class that is specified
- belongs to the innermost enclosing non-class scope,
- but if it is subsequently referenced, its name is not
- found by name lookup until a matching declaration is
- provided in the innermost enclosing nonclass scope.
+ scope. For a friend function declaration, if there is
+ no prior declaration, the program is ill-formed. For a
+ friend class declaration, if there is no prior
+ declaration, the class that is specified belongs to the
+ innermost enclosing non-class scope, but if it is
+ 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 &&
- LOCAL_CLASS_P (current_class_type));
-
- /* 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);
+ gcc_assert (TREE_CODE (binding) == TYPE_DECL);
+ continue;
}
val = binding;
break;