From: mmitchel Date: Sun, 23 Jul 2006 20:28:26 +0000 (+0000) Subject: PR c++/28025 X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=1fb8fb567e1d783d7e55ed80d673968e33aa8699 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. 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 50f8381f946..a5848b82aa8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2006-07-23 Mark Mitchell + + 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 * decl2.c (determine_visibility): Don't propagate visibility from diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 20e704cc2f3..e02d3d7b5bb 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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)) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 78838b06b2b..14977496bab 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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) diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 7cc2fee5329..cdf9ccf1eac 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -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; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 76deddd04ae..e76ad2db346 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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 friend class F; + }; + template struct B { + template 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: diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index c739d613241..e96ba68b034 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b38a1efd4cd..c1a42d65aa5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-07-23 Mark Mitchell + + PR c++/28025 + * g++.dg/template/friend45.C: New test. + 2006-07-21 Jerry DeLisle 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 index 00000000000..61c36561749 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend45.C @@ -0,0 +1,17 @@ +// PR c++/28025 + +class BaseSubmit +{ + template friend class PeriodicSubmit; +}; + +template +class ValuesSubmit +{ + template friend class PeriodicSubmit; +}; + +class A; +class MultiSubmit : public ValuesSubmit +{ +};