diff options
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 15 | ||||
-rw-r--r-- | gcc/cp/name-lookup.h | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/lookup/friend17.C | 9 |
4 files changed, 30 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 743e059..90c76ff 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2016-02-16 Jason Merrill <jason@redhat.com> + + PR c++/69657 + * name-lookup.c (lookup_qualified_name): Add find_hidden parm. + (set_decl_namespace): Pass it. Complain about finding a hidden friend. + * name-lookup.h: Adjust. + 2016-02-16 James Norris <jnorris@codesourcery.com> * parser.c (cp_parser_oacc_data_clause_deviceptr): Remove checking. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index b5961e5..b73f3f7 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -3502,7 +3502,8 @@ set_decl_namespace (tree decl, tree scope, bool friendp) } /* See whether this has been declared in the namespace. */ - old = lookup_qualified_name (scope, DECL_NAME (decl), false, true); + old = lookup_qualified_name (scope, DECL_NAME (decl), /*type*/false, + /*complain*/true, /*hidden*/true); if (old == error_mark_node) /* No old declaration at all. */ goto complain; @@ -3565,6 +3566,12 @@ set_decl_namespace (tree decl, tree scope, bool friendp) { if (!is_associated_namespace (scope, CP_DECL_CONTEXT (found))) goto complain; + if (DECL_HIDDEN_FRIEND_P (found)) + { + pedwarn (DECL_SOURCE_LOCATION (decl), 0, + "%qD has not been declared within %D", decl, scope); + inform (DECL_SOURCE_LOCATION (found), "only here as a friend"); + } DECL_CONTEXT (decl) = DECL_CONTEXT (found); return; } @@ -4509,11 +4516,15 @@ unqualified_namespace_lookup (tree name, int flags) neither a class-type nor a namespace a diagnostic is issued. */ tree -lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain) +lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain, + bool find_hidden) { int flags = 0; tree t = NULL_TREE; + if (find_hidden) + flags |= LOOKUP_HIDDEN; + if (TREE_CODE (scope) == NAMESPACE_DECL) { struct scope_binding binding = EMPTY_SCOPE_BINDING; diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index bce12bb..7e39b6c 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -327,7 +327,7 @@ extern tree namespace_binding (tree, tree); extern void set_namespace_binding (tree, tree, tree); extern bool hidden_name_p (tree); extern tree remove_hidden_names (tree); -extern tree lookup_qualified_name (tree, tree, bool, bool); +extern tree lookup_qualified_name (tree, tree, bool, bool, /*hidden*/bool = false); extern tree lookup_name_nonclass (tree); extern tree lookup_name_innermost_nonclass_level (tree); extern bool is_local_extern (tree); diff --git a/gcc/testsuite/g++.dg/lookup/friend17.C b/gcc/testsuite/g++.dg/lookup/friend17.C new file mode 100644 index 0000000..46b6be5 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/friend17.C @@ -0,0 +1,9 @@ +// PR c++/69657 +// { dg-options "-Wpedantic" } + +namespace N { + struct A { + friend void f(A); + }; +} +void N::f(A) { } // { dg-warning "declared" } |