re PR c++/69657 (abs() not inlined after including math.h)
authorJason Merrill <jason@redhat.com>
Tue, 16 Feb 2016 19:01:49 +0000 (14:01 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 16 Feb 2016 19:01:49 +0000 (14:01 -0500)
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.

From-SVN: r233470

gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/cp/name-lookup.h
gcc/testsuite/g++.dg/lookup/friend17.C [new file with mode: 0644]

index 743e059956a60c6c4a365381b6582d6837d13849..90c76ffcd4efeb52f2775828d059edb004ba5b82 100644 (file)
@@ -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.
index b5961e573f3ebb31671d826ab2c3cf17804ac068..b73f3f7345fc10b14dd04c4517e06f45bd2ed589 100644 (file)
@@ -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;
index bce12bbb26baabcc6ded0dcbf535b8570bba6073..7e39b6c92e07f92f664d2109689959fefa5bb0dc 100644 (file)
@@ -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 (file)
index 0000000..46b6be5
--- /dev/null
@@ -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" }