Commit 944e9f5f by Jason Merrill Committed by Jason Merrill

PR c++/69323 - errors

	* friend.c (make_friend_class): Likewise.
	* decl.c (lookup_and_check_tag): Diagnose invalid dependent friend.

From-SVN: r233682
parent b8599b68
2016-02-24 Jason Merrill <jason@redhat.com> 2016-02-24 Jason Merrill <jason@redhat.com>
PR c++/69323 PR c++/69323
* friend.c (make_friend_class): Likewise.
* decl.c (lookup_and_check_tag): Diagnose invalid dependent friend.
2016-02-24 Jason Merrill <jason@redhat.com>
PR c++/69323
* pt.c (instantiate_class_template_1): Set * pt.c (instantiate_class_template_1): Set
processing_template_decl before substituting friend_type. processing_template_decl before substituting friend_type.
......
...@@ -12590,6 +12590,20 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, ...@@ -12590,6 +12590,20 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
decl, decl,
template_header_p template_header_p
| DECL_SELF_REFERENCE_P (decl)); | DECL_SELF_REFERENCE_P (decl));
if (template_header_p && t && CLASS_TYPE_P (t)
&& (!CLASSTYPE_TEMPLATE_INFO (t)
|| (!PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))))
{
error ("%qT is not a template", t);
inform (location_of (t), "previous declaration here");
if (TYPE_CLASS_SCOPE_P (t)
&& CLASSTYPE_TEMPLATE_INFO (TYPE_CONTEXT (t)))
inform (input_location,
"perhaps you want to explicitly add %<%T::%>",
TYPE_CONTEXT (t));
t = error_mark_node;
}
return t; return t;
} }
else if (decl && TREE_CODE (decl) == TREE_LIST) else if (decl && TREE_CODE (decl) == TREE_LIST)
......
...@@ -255,6 +255,18 @@ make_friend_class (tree type, tree friend_type, bool complain) ...@@ -255,6 +255,18 @@ make_friend_class (tree type, tree friend_type, bool complain)
friend_type); friend_type);
return; return;
} }
if (TYPE_TEMPLATE_INFO (friend_type)
&& !PRIMARY_TEMPLATE_P (TYPE_TI_TEMPLATE (friend_type)))
{
error ("%qT is not a template", friend_type);
inform (location_of (friend_type), "previous declaration here");
if (TYPE_CLASS_SCOPE_P (friend_type)
&& CLASSTYPE_TEMPLATE_INFO (TYPE_CONTEXT (friend_type))
&& currently_open_class (TYPE_CONTEXT (friend_type)))
inform (input_location, "perhaps you need explicit template "
"arguments in your nested-name-specifier");
return;
}
} }
else if (same_type_p (type, friend_type)) else if (same_type_p (type, friend_type))
{ {
......
...@@ -7,6 +7,6 @@ ...@@ -7,6 +7,6 @@
class Foo; class Foo;
template <typename T> class Foo { }; // { dg-error "not a template type" } template <typename T> class Foo { }; // { dg-error "not a template" }
Foo<int> x; // { dg-error "not a template|incomplete type" } Foo<int> x; // { dg-error "not a template|incomplete type" }
// PR c++/69323
template<int VALUE>
struct Outer
{
struct StupidValueTrick
{
template<int VAL> friend struct StupidValueTrick; // { dg-error "not a template" }
};
};
typedef Outer<42>::StupidValueTrick GoodValue;
GoodValue good;
// PR c++/69323
template<int VALUE>
struct Outer
{
struct StupidValueTrick
{
template<int VAL> friend struct Outer::StupidValueTrick; // { dg-error "not a template" }
};
};
typedef Outer<42>::StupidValueTrick GoodValue;
GoodValue good;
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