This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix PR c++/30917: ICE with friend in local class (to a function)


Hi all.

The initial patch:
http://gcc.gnu.org/ml/gcc-patches/2007-03/msg00463.html

has been approved by Mark modulo some minor changes here:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30917#c5

I attach the updated patch (the testsuite bits are unchanged), that I
have successfully tested again on i386-apple-darwin8.10.1, and committed
to the trunk.

I'll test it against 4.2, and commit it there if testing succeeds.

Best regards,
Simon


2007-07-28  Simon Martin  <simartin@users.sourceforge.net>
	    Mark Mitchell  <mark@codesourcery.com>

	PR c++/30917
	* name-lookup.c (lookup_name_real): Non namespace-scope bindings can be
	hidden due to friend declarations in local classes.

Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c	(revision 126993)
+++ gcc/cp/name-lookup.c	(working copy)
@@ -3990,8 +3990,49 @@ lookup_name_real (tree name, int prefer_
 
 	if (binding)
 	  {
-	    /* Only namespace-scope bindings can be hidden.  */
-	    gcc_assert (!hidden_name_p (binding));
+	    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.
+		   In particular, consider:
+
+		   void f() {
+		     struct A {
+		       friend struct B;
+		       void g() { B* b; } // error: B is hidden
+		     }
+		     struct B {};
+		   }
+
+		   The standard says that "B" is a local class in "f"
+		   (but not nested within "A") -- but that name lookup
+		   for "B" does not find this declaration until it is
+		   declared directly with "f".
+
+		   In particular:
+
+		   [class.friend]
+
+		   If a friend declaration appears in a local class and
+		   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.
+		*/
+		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);
+	      }
 	    val = binding;
 	    break;
 	  }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]