diff options
author | Jason Merrill <jason@redhat.com> | 2016-02-24 14:56:09 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-02-24 14:56:09 -0500 |
commit | 944e9f5feea2ef45badd508d639f2b5802f3824d (patch) | |
tree | ae495e7ade17d9b968493c2f5505766ce0eb7d33 /gcc | |
parent | b8599b68edc1626c905752d56b6c9b99ac89f126 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/decl.c | 14 | ||||
-rw-r--r-- | gcc/cp/friend.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/crash34.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/friend61a.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/friend61b.C | 12 |
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; |