Commit 77adef84 by Mark Mitchell Committed by Mark Mitchell

re PR c++/6256 (Seg fault for template friends in namespaces, regression from 2.95)

	PR c++/6256:
	* pt.c (tsubst_friend_class): Handle templates with explicit
	nested names.

	PR c++/6331:
	* typeck.c (merge_types): Remember the cv-qualification of pointer
	types when merging them.

	PR c++/6256:
	* g++.dg/template/friend5.C: New test.

	PR c++/6331:
	* g++.dg/template/qual1.C: Likewise.

From-SVN: r52661
parent 8d3441e0
2002-04-23 Mark Mitchell <mark@codesourcery.com>
PR c++/6256:
* pt.c (tsubst_friend_class): Handle templates with explicit
nested names.
PR c++/6331:
* typeck.c (merge_types): Remember the cv-qualification of pointer
types when merging them.
2002-04-20 Neil Booth <neil@daikokuya.demon.co.uk>
* cp-lang.c (LANG_HOOKS_FUNCTION_INIT,
......
......@@ -4833,23 +4833,28 @@ tsubst_friend_class (friend_tmpl, args)
tree tmpl;
/* First, we look for a class template. */
tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/0);
/* But, if we don't find one, it might be because we're in a
situation like this:
if (DECL_CONTEXT (friend_tmpl))
tmpl = friend_tmpl;
else
{
tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/0);
template <class T>
struct S {
template <class U>
friend struct S;
};
/* But, if we don't find one, it might be because we're in a
situation like this:
Here, in the scope of (say) S<int>, `S' is bound to a TYPE_DECL
for `S<int>', not the TEMPLATE_DECL. */
if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
{
tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/1);
tmpl = maybe_get_template_decl_from_type_decl (tmpl);
template <class T>
struct S {
template <class U>
friend struct S;
};
Here, in the scope of (say) S<int>, `S' is bound to a TYPE_DECL
for `S<int>', not the TEMPLATE_DECL. */
if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
{
tmpl = lookup_name (DECL_NAME (friend_tmpl), /*prefer_type=*/1);
tmpl = maybe_get_template_decl_from_type_decl (tmpl);
}
}
if (tmpl && DECL_CLASS_TEMPLATE_P (tmpl))
......
......@@ -592,12 +592,14 @@ merge_types (t1, t2)
/* For two pointers, do this recursively on the target type. */
{
tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
int quals = cp_type_quals (t1);
if (code1 == POINTER_TYPE)
t1 = build_pointer_type (target);
else
t1 = build_reference_type (target);
t1 = build_type_attribute_variant (t1, attributes);
t1 = cp_build_qualified_type (t1, quals);
if (TREE_CODE (target) == METHOD_TYPE)
t1 = build_ptrmemfunc_type (t1);
......
2002-04-23 Mark Mitchell <mark@codesourcery.com>
PR c++/6256:
* g++.dg/template/friend5.C: New test.
PR c++/6331:
* g++.dg/template/qual1.C: Likewise.
2002-04-22 Zack Weinberg <zack@codesourcery.com>
* gcc.c-torture/execute/980707-1.c: Don't use isspace().
......
// { dg-do compile }
namespace NS { template <typename number> class C; }
template <typename T> class X {
template <typename N> friend class NS::C;
};
template class X<int>;
// { dg-do compile }
template<class T>
class Link_array
{
public:
void sort (int (*compare) (T *const&,T *const&));
};
int shift_compare (int *const &, int *const &) {};
template<class T> void
Link_array<T>::sort (int (*compare) (T *const&,T *const&))
{
}
void f ()
{
Link_array<int> clashes;
clashes.sort (shift_compare);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment