OSDN Git Service

PR c++/28025
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 23 Jul 2006 20:28:26 +0000 (20:28 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 23 Jul 2006 20:28:26 +0000 (20:28 +0000)
* cp-tree.h (LOOKUP_HIDDEN): New macro.  Reformat comments.
* name-lookup.c (unqualified_namespace_lookup): There is no way to
have a hidden name in non-namespace scopes.
* pt.c (tsubst_friend_class): Look for hidden names.
* decl.c (lookup_and_check_tag): Fix typo in comment.
* semantics.c (finish_compound_literal): Fix typo in comment.
PR c++/28025
* g++.dg/template/friend45.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@115687 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/name-lookup.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/friend45.C [new file with mode: 0644]

index 50f8381..a5848b8 100644 (file)
@@ -1,3 +1,14 @@
+2006-07-23  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/28025
+       * cp-tree.h (LOOKUP_HIDDEN): New macro.  Reformat comments.
+       * name-lookup.c (unqualified_namespace_lookup): There is no way to
+       have a hidden name in non-namespace scopes.
+       * pt.c (tsubst_friend_class): Look for hidden names.
+       * decl.c (lookup_and_check_tag): Fix typo in comment.
+
+       * semantics.c (finish_compound_literal): Fix typo in comment.
+
 2006-07-21  Jason Merrill  <jason@redhat.com>
 
        * decl2.c (determine_visibility): Don't propagate visibility from
index 20e704c..e02d3d7 100644 (file)
@@ -3380,46 +3380,51 @@ extern GTY(()) tree static_dtors;
 
 enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
 
-/* These are uses as bits in flags passed to build_new_method_call
-   to control its error reporting behavior.
-
-   LOOKUP_PROTECT means flag access violations.
-   LOOKUP_COMPLAIN mean complain if no suitable member function
-     matching the arguments is found.
-   LOOKUP_NORMAL is just a combination of these two.
-   LOOKUP_NONVIRTUAL means make a direct call to the member function found
-   LOOKUP_ONLYCONVERTING means that non-conversion constructors are not tried.
-   DIRECT_BIND means that if a temporary is created, it should be created so
-     that it lives as long as the current variable bindings; otherwise it
-     only lives until the end of the complete-expression.  It also forces
-     direct-initialization in cases where other parts of the compiler have
-     already generated a temporary, such as reference initialization and the
-     catch parameter.
-   LOOKUP_NO_CONVERSION means that user-defined conversions are not
-     permitted.  Built-in conversions are permitted.
-   LOOKUP_DESTRUCTOR means explicit call to destructor.
-   LOOKUP_NO_TEMP_BIND means temporaries will not be bound to references.
-
-   These are used in global lookup to support elaborated types and
-   qualifiers.
-
-   LOOKUP_PREFER_TYPES means not to accept objects, and possibly namespaces.
-   LOOKUP_PREFER_NAMESPACES means not to accept objects, and possibly types.
-   LOOKUP_PREFER_BOTH means class-or-namespace-name.  */
-
+/* These are uses as bits in flags passed to various functions to
+   control their behavior.  Despite the LOOKUP_ prefix, many of these
+   do not control name lookup.  ??? Functions using these flags should
+   probably be modified to accept explicit boolean flags for the
+   behaviors relevant to them.  */
+/* Check for access violations.  */
 #define LOOKUP_PROTECT (1 << 0)
+/* Complain if no suitable member function matching the arguments is
+   found.  */
 #define LOOKUP_COMPLAIN (1 << 1)
 #define LOOKUP_NORMAL (LOOKUP_PROTECT | LOOKUP_COMPLAIN)
+/* Even if the function found by lookup is a virtual function, it
+   should be called directly.  */
 #define LOOKUP_NONVIRTUAL (1 << 2)
+/* Non-converting (i.e., "explicit") constructors are not tried.  */
 #define LOOKUP_ONLYCONVERTING (1 << 3)
+/* If a temporary is created, it should be created so that it lives
+   as long as the current variable bindings; otherwise it only lives
+   until the end of the complete-expression.  It also forces
+   direct-initialization in cases where other parts of the compiler
+   have already generated a temporary, such as reference
+   initialization and the catch parameter.  */
 #define DIRECT_BIND (1 << 4)
+/* User-defined conversions are not permitted.  (Built-in conversions
+   are permitted.)  */
 #define LOOKUP_NO_CONVERSION (1 << 5)
+/* The user has explicitly called a destructor.  (Therefore, we do
+   not need to check that the object is non-NULL before calling the
+   destructor.)  */
 #define LOOKUP_DESTRUCTOR (1 << 6)
+/* Do not permit references to bind to temporaries.  */
 #define LOOKUP_NO_TEMP_BIND (1 << 7)
+/* Do not accept objects, and possibly namespaces.  */
 #define LOOKUP_PREFER_TYPES (1 << 8)
+/* Do not accept objects, and possibly types.   */
 #define LOOKUP_PREFER_NAMESPACES (1 << 9)
+/* Accept types or namespaces.  */
 #define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES)
+/* We are checking that a constructor can be called -- but we do not
+   actually plan to call it.  */
 #define LOOKUP_CONSTRUCTOR_CALLABLE (1 << 10)
+/* Return friend decarations and un-declared builtin functions.
+   (Normally, these entities are registered in the symbol table, but
+   not found by lookup.)  */
+#define LOOKUP_HIDDEN (LOOKUP_CONSTRUCTOR_CALLABLE << 1)
 
 #define LOOKUP_NAMESPACES_ONLY(F)  \
   (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
index 78838b0..1497749 100644 (file)
@@ -9503,7 +9503,7 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
       /* If that fails, the name will be placed in the smallest
         non-class, non-function-prototype scope according to 3.3.1/5.
         We may already have a hidden name declared as friend in this
-        scope.  So lookup again but not ignoring hidden name.
+        scope.  So lookup again but not ignoring hidden names.
         If we find one, that name will be made visible rather than
         creating a new tag.  */
       if (!decl)
index 7cc2fee..cdf9ccf 100644 (file)
@@ -3681,10 +3681,8 @@ unqualified_namespace_lookup (tree name, int flags)
 
       if (b)
        {
-         if (b->value && hidden_name_p (b->value))
-           /* Ignore anticipated built-in functions and friends.  */
-           ;
-         else
+         if (b->value
+             && ((flags & LOOKUP_HIDDEN) || !hidden_name_p (b->value)))
            binding.value = b->value;
          binding.type = b->type;
        }
@@ -3987,18 +3985,18 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p,
          continue;
 
        /* If this is the kind of thing we're looking for, we're done.  */
-       if (qualify_lookup (iter->value, flags)
-           && !hidden_name_p (iter->value))
+       if (qualify_lookup (iter->value, flags))
          binding = iter->value;
        else if ((flags & LOOKUP_PREFER_TYPES)
-                && qualify_lookup (iter->type, flags)
-                && !hidden_name_p (iter->type))
+                && qualify_lookup (iter->type, flags))
          binding = iter->type;
        else
          binding = NULL_TREE;
 
        if (binding)
          {
+           /* Only namespace-scope bindings can be hidden.  */
+           gcc_assert (!hidden_name_p (binding));
            val = binding;
            break;
          }
index 76deddd..e76ad2d 100644 (file)
@@ -5408,8 +5408,21 @@ tsubst_friend_class (tree friend_tmpl, tree args)
        push_nested_class (tsubst (context, args, tf_none, NULL_TREE));
     }
 
-  /* First, we look for a class template.  */
-  tmpl = lookup_name (DECL_NAME (friend_tmpl));
+  /* Look for a class template declaration.  We look for hidden names
+     because two friend declarations of the same template are the
+     same.  For example, in:
+
+       struct A { 
+         template <typename> friend class F;
+       };
+       template <typename> struct B { 
+         template <typename> friend class F;
+       };
+
+     both F templates are the same.  */
+  tmpl = lookup_name_real (DECL_NAME (friend_tmpl), 0, 0,
+                          /*block_p=*/true, 0, 
+                          LOOKUP_COMPLAIN | LOOKUP_HIDDEN);
 
   /* But, if we don't find one, it might be because we're in a
      situation like this:
index c739d61..e96ba68 100644 (file)
@@ -2058,7 +2058,7 @@ finish_compound_literal (tree type, VEC(constructor_elt,gc) *initializer_list)
       DECL_NAME (var) = make_anon_name ();
     }
   /* We must call pushdecl, since the gimplifier complains if the
-     variable hase been declared via a BIND_EXPR.  */
+     variable has not been declared via a BIND_EXPR.  */
   pushdecl (var);
   /* Initialize the variable as we would any other variable with a
      brace-enclosed initializer.  */
index b38a1ef..c1a42d6 100644 (file)
@@ -1,3 +1,8 @@
+2006-07-23  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/28025
+       * g++.dg/template/friend45.C: New test.
+
 2006-07-21  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR libgfortran/28339
diff --git a/gcc/testsuite/g++.dg/template/friend45.C b/gcc/testsuite/g++.dg/template/friend45.C
new file mode 100644 (file)
index 0000000..61c3656
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/28025
+
+class BaseSubmit
+{
+  template<class T> friend class PeriodicSubmit;
+};
+
+template<class ID>
+class ValuesSubmit 
+{
+  template<class T> friend class PeriodicSubmit;
+};
+
+class A;
+class MultiSubmit : public ValuesSubmit<A>
+{
+};