2018-02-16  Nathan Sidwell  <nathan@acm.org>

	Deprecate -ffriend-injection.
	* decl.c (cxx_init_decl_processing): Emit warning on option.
	* name-lookup.c (do_pushdecl): Emit warning if we push a visible
	friend.

	* doc/extend.texi (Backwards Compatibility): Mention friend
	injection.  Note for-scope is deprecated.
	* doc/invoke.texi (-ffriend-injection): Deprecate.

	* g++.old-deja/g++.jason/scoping15.C: Expect warnings.
	* g++.old-deja/g++.mike/net43.C: Likewise.

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 257739)
+++ cp/decl.c	(working copy)
@@ -4091,8 +4091,14 @@ cxx_init_decl_processing (void)
   pop_namespace ();
 
   flag_noexcept_type = (cxx_dialect >= cxx17);
+  /* There's no fixed location for <command-line>, the current
+     location is <builtins>, which is somewhat confusing.  */
   if (!flag_new_for_scope)
-    warning (OPT_Wdeprecated, "%<-fno-for-scope%> is deprecated");
+    warning_at (UNKNOWN_LOCATION, OPT_Wdeprecated,
+		"%<-fno-for-scope%> is deprecated");
+  if (flag_friend_injection)
+    warning_at (UNKNOWN_LOCATION, OPT_Wdeprecated,
+		"%<-ffriend-injection%> is deprecated");
 
   c_common_nodes_and_builtins ();
 
Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c	(revision 257739)
+++ cp/name-lookup.c	(working copy)
@@ -3071,6 +3071,7 @@ do_pushdecl (tree decl, bool is_friend)
 	old = OVL_CHAIN (old);
 
       check_template_shadow (decl);
+      bool visible_injection = false;
 
       if (DECL_DECLARES_FUNCTION_P (decl))
 	{
@@ -3091,6 +3092,8 @@ do_pushdecl (tree decl, bool is_friend)
 	      if (!flag_friend_injection)
 		/* Hide it from ordinary lookup.  */
 		DECL_ANTICIPATED (decl) = DECL_HIDDEN_FRIEND_P (decl) = true;
+	      else
+		visible_injection = true;
 	    }
 	}
 
@@ -3142,6 +3145,9 @@ do_pushdecl (tree decl, bool is_friend)
 	}
       else if (VAR_P (decl))
 	maybe_register_incomplete_var (decl);
+      else if (visible_injection)
+	warning (0, "injected friend %qD is visible"
+		" due to %<-ffriend-injection%>", decl);
 
       if ((VAR_P (decl) || TREE_CODE (decl) == FUNCTION_DECL)
 	  && DECL_EXTERN_C_P (decl))
Index: doc/extend.texi
===================================================================
--- doc/extend.texi	(revision 257739)
+++ doc/extend.texi	(working copy)
@@ -23881,11 +23881,23 @@ deprecated.   @xref{Deprecated Features}
 
 @table @code
 @item For scope
-If a variable is declared at for scope, it used to remain in scope until
-the end of the scope that contained the for statement (rather than just
-within the for scope).  G++ retains this, but issues a warning, if such a
+If a variable is declared at for scope, it used to remain in scope
+until the end of the scope that contained the for statement (rather
+than just within the for scope).  The deprecated
+@option{-fno-for-scope} option enables this non-standard behaviour.
+Without the option, G++ retains this, but issues a warning, if such a
 variable is accessed outside the for scope.
 
+The behaviour is deprecated, only available with @option{-std=c++98}
+@option{-std=gnu++98} languages and you must use the
+@option{-fpermissive} option to enable it.  The behaviour will be
+removed.
+
+@item Friend Injection
+The @option{-ffriend-injection} option makes injected friends visible
+to regular name lookup, unlike standard C++.  This option is
+deprecated and will be removed.
+
 @item Implicit C language
 Old C system header files did not contain an @code{extern "C" @{@dots{}@}}
 scope to set the language.  On such systems, all header files are
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 257739)
+++ doc/invoke.texi	(working copy)
@@ -2451,8 +2451,7 @@ However, in ISO C++ a friend function th
 in an enclosing scope can only be found using argument dependent
 lookup.  GCC defaults to the standard behavior.
 
-This option is for compatibility, and may be removed in a future
-release of G++.
+This option is deprecated and will be removed.
 
 @item -fno-elide-constructors
 @opindex fno-elide-constructors
Index: testsuite/g++.old-deja/g++.jason/scoping15.C
===================================================================
--- testsuite/g++.old-deja/g++.jason/scoping15.C	(revision 257739)
+++ testsuite/g++.old-deja/g++.jason/scoping15.C	(working copy)
@@ -3,14 +3,17 @@
 // Bug: g++ ignores the :: qualification and dies trying to treat an integer
 // variable as a list of functions.
 
+class DComplex;
+double imag (const DComplex&);
+
 class DComplex {
 public:
-  friend  double   imag(const DComplex& a);
+  friend  double   imag(const DComplex& a); // Not injected, no warning
 };
 
 class FComplex {
 public:
-  friend  float    imag(const FComplex& a);
+  friend  float    imag(const FComplex& a); // { dg-warning "is visible"
 };
 
 void
@@ -19,3 +22,4 @@ scnrm2(FComplex cx[])
   int imag;
   ::imag( cx[0] );
 }
+// { dg-warning "ffriend-injection.* is deprecated" "" { target *-*-* } cc1plus: }
Index: testsuite/g++.old-deja/g++.mike/net43.C
===================================================================
--- testsuite/g++.old-deja/g++.mike/net43.C	(revision 257739)
+++ testsuite/g++.old-deja/g++.mike/net43.C	(working copy)
@@ -1,9 +1,9 @@
 // { dg-do assemble  }
-// { dg-options "-ffriend-injection" }
+// { dg-options "-ffriend-injection -Wno-deprecated" }
 
 class foo {
  public:
-   friend int operator ^(const foo&, const foo&);
+  friend int operator ^(const foo&, const foo&); // { dg-message "is visible" }
 };
 
 int main ()
