aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-02-24 14:56:09 -0500
committerJason Merrill <jason@gcc.gnu.org>2016-02-24 14:56:09 -0500
commit944e9f5feea2ef45badd508d639f2b5802f3824d (patch)
treeae495e7ade17d9b968493c2f5505766ce0eb7d33 /gcc
parentb8599b68edc1626c905752d56b6c9b99ac89f126 (diff)
downloadgcc-944e9f5feea2ef45badd508d639f2b5802f3824d.zip
gcc-944e9f5feea2ef45badd508d639f2b5802f3824d.tar.gz
gcc-944e9f5feea2ef45badd508d639f2b5802f3824d.tar.bz2
PR c++/69323 - errors
* friend.c (make_friend_class): Likewise. * decl.c (lookup_and_check_tag): Diagnose invalid dependent friend. From-SVN: r233682
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl.c14
-rw-r--r--gcc/cp/friend.c12
-rw-r--r--gcc/testsuite/g++.dg/template/crash34.C2
-rw-r--r--gcc/testsuite/g++.dg/template/friend61a.C12
-rw-r--r--gcc/testsuite/g++.dg/template/friend61b.C12
6 files changed, 57 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8fe4306..897c28f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,6 +1,12 @@
2016-02-24 Jason Merrill <jason@redhat.com>
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
processing_template_decl before substituting friend_type.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 2df3398..5ec6589 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -12590,6 +12590,20 @@ lookup_and_check_tag (enum tag_types tag_code, tree name,
decl,
template_header_p
| 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;
}
else if (decl && TREE_CODE (decl) == TREE_LIST)
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c
index 36b000f..5e4b2d1 100644
--- a/gcc/cp/friend.c
+++ b/gcc/cp/friend.c
@@ -255,6 +255,18 @@ make_friend_class (tree type, tree friend_type, bool complain)
friend_type);
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))
{
diff --git a/gcc/testsuite/g++.dg/template/crash34.C b/gcc/testsuite/g++.dg/template/crash34.C
index ef4d21b..83dcc78 100644
--- a/gcc/testsuite/g++.dg/template/crash34.C
+++ b/gcc/testsuite/g++.dg/template/crash34.C
@@ -7,6 +7,6 @@
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" }
diff --git a/gcc/testsuite/g++.dg/template/friend61a.C b/gcc/testsuite/g++.dg/template/friend61a.C
new file mode 100644
index 0000000..d38e53a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/friend61a.C
@@ -0,0 +1,12 @@
+// 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;
diff --git a/gcc/testsuite/g++.dg/template/friend61b.C b/gcc/testsuite/g++.dg/template/friend61b.C
new file mode 100644
index 0000000..2da5d60
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/friend61b.C
@@ -0,0 +1,12 @@
+// 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;