From: Jason Merrill Date: Wed, 24 Feb 2016 19:56:09 +0000 (-0500) Subject: PR c++/69323 - errors X-Git-Tag: basepoints/gcc-7~768 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=944e9f5feea2ef45badd508d639f2b5802f3824d;p=thirdparty%2Fgcc.git PR c++/69323 - errors * friend.c (make_friend_class): Likewise. * decl.c (lookup_and_check_tag): Diagnose invalid dependent friend. From-SVN: r233682 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8fe43069e737..897c28fe4ff1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-02-24 Jason Merrill + + PR c++/69323 + * friend.c (make_friend_class): Likewise. + * decl.c (lookup_and_check_tag): Diagnose invalid dependent friend. + 2016-02-24 Jason Merrill PR c++/69323 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 2df3398d6c03..5ec65892e68d 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 36b000fb34ec..5e4b2d18bf74 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 ef4d21b60d84..83dcc78f37fe 100644 --- a/gcc/testsuite/g++.dg/template/crash34.C +++ b/gcc/testsuite/g++.dg/template/crash34.C @@ -7,6 +7,6 @@ class Foo; -template class Foo { }; // { dg-error "not a template type" } +template class Foo { }; // { dg-error "not a template" } Foo 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 000000000000..d38e53ae4bb7 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend61a.C @@ -0,0 +1,12 @@ +// PR c++/69323 + +template +struct Outer +{ + struct StupidValueTrick + { + template 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 000000000000..2da5d60b55e3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend61b.C @@ -0,0 +1,12 @@ +// PR c++/69323 + +template +struct Outer +{ + struct StupidValueTrick + { + template friend struct Outer::StupidValueTrick; // { dg-error "not a template" } + }; +}; +typedef Outer<42>::StupidValueTrick GoodValue; +GoodValue good;