mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 10:30:53 +08:00
re PR c++/28025 (multiple template friend compile error)
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. From-SVN: r115687
This commit is contained in:
parent
74e55d0f8f
commit
105d72c595
gcc
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
17
gcc/cp/pt.c
17
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 <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:
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
17
gcc/testsuite/g++.dg/template/friend45.C
Normal file
17
gcc/testsuite/g++.dg/template/friend45.C
Normal file
@ -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>
|
||||
{
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user