From f795360d35caef4aa3a17015f415e8f3b200a3e5 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 31 May 2016 15:16:26 -0400 Subject: [PATCH] PR c++/71227 - specializing hidden friend * pt.c (check_explicit_specialization): Give better diagnostic about specializing a hidden friend. From-SVN: r236941 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/pt.c | 16 ++++++++++++++++ gcc/testsuite/g++.dg/template/friend62.C | 16 ++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 gcc/testsuite/g++.dg/template/friend62.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0401255dad7..35042bc262d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-05-31 Jason Merrill + + PR c++/71227 + * pt.c (check_explicit_specialization): Give better diagnostic about + specializing a hidden friend. + 2016-05-31 Paolo Carlini PR c++/71248 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 4a24c9840fc..af375861772 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2808,6 +2808,13 @@ check_explicit_specialization (tree declarator, context. */ fns = lookup_qualified_name (CP_DECL_CONTEXT (decl), dname, false, true); + if (fns == error_mark_node) + /* If lookup fails, look for a friend declaration so we can + give a better diagnostic. */ + fns = lookup_qualified_name (CP_DECL_CONTEXT (decl), dname, + /*type*/false, /*complain*/true, + /*hidden*/true); + if (fns == error_mark_node || !is_overloaded_fn (fns)) { error ("%qD is not a template function", dname); @@ -2953,6 +2960,15 @@ check_explicit_specialization (tree declarator, CP_DECL_CONTEXT (tmpl))) error ("%qD is not declared in %qD", tmpl, current_namespace); + else if (TREE_CODE (decl) == FUNCTION_DECL + && DECL_HIDDEN_FRIEND_P (tmpl)) + { + if (pedwarn (DECL_SOURCE_LOCATION (decl), 0, + "friend declaration %qD is not visible to " + "explicit specialization", tmpl)) + inform (DECL_SOURCE_LOCATION (tmpl), + "friend declaration here"); + } tree gen_tmpl = most_general_template (tmpl); diff --git a/gcc/testsuite/g++.dg/template/friend62.C b/gcc/testsuite/g++.dg/template/friend62.C new file mode 100644 index 00000000000..c9796c49205 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend62.C @@ -0,0 +1,16 @@ +// PR c++/71227 +// { dg-options "" } + +class A { + public: + template + friend int f(int x, T v) { // { dg-message "declaration" } + return x + v; + } +}; + + +template<> +int f(int x, int v) { // { dg-warning "friend" } + return x + v; +} -- 2.30.2