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]

PATCH: fixes c++ friend class declaration lookup bugs


If a friend class declaration has no prior declarations, the class
name is hidden from name lookup until it is subsequently declared.  In
some cases, the hidden name is stored in the type member of its
cxx_binding structure.  However, the name lookup code was not always
checking this.  This resulted in types being found prior to their
declaration and, in one case, an internal compiler error.  This patch
adds missing checks via the hidden_name_p macro.

Tested with a C/C++/Java bootstrap and testsuite run on i686-pc-linux-gnu.

Ollie

:ADDPATCH c++:

2007-05-18 Ollie Wild <aaw@google.com>

      * name-lookup.c (ambiguous_decl): Adds check for hidden types.
      (unqualified_namespace_lookup): Adds check for hidden types.

2007-05-18 Ollie Wild <aaw@google.com>

      * g++.dg/lookup/hidden-class10.C: New test.
      * g++.dg/lookup/hidden-class11.C: New test.
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index a7a12cd..befc2d3 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3543,7 +3543,7 @@ ambiguous_decl (tree name, struct scope_binding *old, cxx_binding *new,
     }
   /* ... and copy the type.  */
   type = new->type;
-  if (LOOKUP_NAMESPACES_ONLY (flags))
+  if (LOOKUP_NAMESPACES_ONLY (flags) || (type && hidden_name_p (type)))
     type = NULL_TREE;
   if (!old->type)
     old->type = type;
@@ -3699,7 +3699,9 @@ unqualified_namespace_lookup (tree name, int flags)
 	  if (b->value
 	      && ((flags & LOOKUP_HIDDEN) || !hidden_name_p (b->value)))
 	    binding.value = b->value;
-	  binding.type = b->type;
+	  if (b->type
+	      && ((flags & LOOKUP_HIDDEN) || !hidden_name_p (b->type)))
+	    binding.type = b->type;
 	}
 
       /* Add all _DECLs seen through local using-directives.  */
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class10.C b/gcc/testsuite/g++.dg/lookup/hidden-class10.C
new file mode 100644
index 0000000..f68196f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class10.C
@@ -0,0 +1,11 @@
+// Copyright (C) 2007 Free Software Foundation
+// Contributed by Ollie Wild <aaw@google.com>
+// { dg-do compile }
+
+// Verify that a friend class is hidden even if it overrides a builtin
+// function name.
+
+class A {
+  friend class abort;
+  abort *b;	// { dg-error "no type|expected" }
+};
diff --git a/gcc/testsuite/g++.dg/lookup/hidden-class11.C b/gcc/testsuite/g++.dg/lookup/hidden-class11.C
new file mode 100644
index 0000000..8432e32
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/hidden-class11.C
@@ -0,0 +1,23 @@
+// Copyright (C) 2007 Free Software Foundation
+// Contributed by Ollie Wild <aaw@google.com>
+// { dg-do compile }
+
+// Verify that a friend class is hidden even if it is hidden by a non-builtin
+// function name.
+
+namespace M {
+  void F (void);
+  class F;
+}
+
+namespace N {
+  void F(void);
+  class A {
+    friend class F;
+  };
+}
+
+using namespace M;
+using namespace N;
+
+class F *b;

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