This patch deprecates 2 sets of extensions

1)  'T v (init) __attribute__ ((ignored))'
That attribute placement has had no effect since the new parser (2002, I think gcc 3.3). Now we're more noisy about it.

2) anonymous struct or union members could be things other than public non-static data members. Now we're noisier about that too.

I updated the 'Deprecated Features' piece of the documentation, it was mentioning some now-removed items as merely deprecated. It occurs to me we should probably just merge the 'Backwards Compatibility' section into 'Deprecated Features'. Perhaps add a 'Removed Features' section too? Sandra, WDYT?

nathan
--
Nathan Sidwell
2018-03-20  Nathan Sidwell  <nat...@acm.org>

	* doc/extend.texi (Deprecated Features): Update deprecared flags,
	mention anon-struct/union members and trailing attributes.

	cp/
	* class.c (finish_struct_anon_r): Refactor, deprecate anything
	other than public non-static data members.
	* parser.c (cp_parser_init_declarator): Deprecate attributes after
	parenthesized initializer.

	testsuite/
	* g++.dg/ext/anon-struct6.C: Adjust.
	* g++.dg/ext/deprecate-1.C: New.
	* g++.dg/ext/deprecate-2.C: New.
	* g++.dg/lookup/pr84602.C: Adjust.
	* g++.dg/lookup/pr84962.C: Adjust.
	* g++.old-deja/g++.other/anon4.C

Index: cp/class.c
===================================================================
--- cp/class.c	(revision 258686)
+++ cp/class.c	(working copy)
@@ -2869,9 +2869,7 @@ warn_hidden (tree t)
 static void
 finish_struct_anon_r (tree field, bool complain)
 {
-  bool is_union = TREE_CODE (TREE_TYPE (field)) == UNION_TYPE;
-  tree elt = TYPE_FIELDS (TREE_TYPE (field));
-  for (; elt; elt = DECL_CHAIN (elt))
+  for (tree elt = TYPE_FIELDS (TREE_TYPE (field)); elt; elt = DECL_CHAIN (elt))
     {
       /* We're generally only interested in entities the user
 	 declared, but we also find nested classes by noticing
@@ -2885,50 +2883,34 @@ finish_struct_anon_r (tree field, bool c
 	      || TYPE_UNNAMED_P (TREE_TYPE (elt))))
 	continue;
 
-      if (TREE_CODE (elt) != FIELD_DECL)
+      if (complain
+	  && (TREE_CODE (elt) != FIELD_DECL
+	      || (TREE_PRIVATE (elt) || TREE_PROTECTED (elt))))
 	{
 	  /* We already complained about static data members in
 	     finish_static_data_member_decl.  */
-	  if (complain && !VAR_P (elt))
+	  if (!VAR_P (elt)
+	      && permerror (DECL_SOURCE_LOCATION (elt),
+			    TREE_CODE (TREE_TYPE (field)) == UNION_TYPE
+			    ? "%q#D invalid; an anonymous union may "
+			    "only have public non-static data members"
+			    : "%q#D invalid; an anonymous struct may "
+			    "only have public non-static data members", elt))
 	    {
-	      if (is_union)
-		permerror (DECL_SOURCE_LOCATION (elt),
-			   "%q#D invalid; an anonymous union can "
-			   "only have non-static data members", elt);
-	      else
-		permerror (DECL_SOURCE_LOCATION (elt),
-			   "%q#D invalid; an anonymous struct can "
-			   "only have non-static data members", elt);
-	    }
-	  continue;
-	}
-
-      if (complain)
-	{
-	  if (TREE_PRIVATE (elt))
-	    {
-	      if (is_union)
-		permerror (DECL_SOURCE_LOCATION (elt),
-			   "private member %q#D in anonymous union", elt);
-	      else
-		permerror (DECL_SOURCE_LOCATION (elt),
-			   "private member %q#D in anonymous struct", elt);
-	    }
-	  else if (TREE_PROTECTED (elt))
-	    {
-	      if (is_union)
-		permerror (DECL_SOURCE_LOCATION (elt),
-			   "protected member %q#D in anonymous union", elt);
-	      else
-		permerror (DECL_SOURCE_LOCATION (elt),
-			   "protected member %q#D in anonymous struct", elt);
+	      static bool hint;
+	      if (flag_permissive && !hint)
+		{
+		  hint = true;
+		  inform (DECL_SOURCE_LOCATION (elt),
+			  "this flexibility is deprecated and will be removed");
+		}
 	    }
 	}
 
       TREE_PRIVATE (elt) = TREE_PRIVATE (field);
       TREE_PROTECTED (elt) = TREE_PROTECTED (field);
 
-      /* Recurse into the anonymous aggregates to handle correctly
+      /* Recurse into the anonymous aggregates to correctly handle
 	 access control (c++/24926):
 
 	 class A {
Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 258686)
+++ cp/parser.c	(working copy)
@@ -19685,12 +19685,21 @@ cp_parser_init_declarator (cp_parser* pa
   /* The old parser allows attributes to appear after a parenthesized
      initializer.  Mark Mitchell proposed removing this functionality
      on the GCC mailing lists on 2002-08-13.  This parser accepts the
-     attributes -- but ignores them.  */
+     attributes -- but ignores them.  Made a permerror in GCC 8.  */
   if (cp_parser_allow_gnu_extensions_p (parser)
-      && initialization_kind == CPP_OPEN_PAREN)
-    if (cp_parser_attributes_opt (parser))
-      warning (OPT_Wattributes,
-	       "attributes after parenthesized initializer ignored");
+      && initialization_kind == CPP_OPEN_PAREN
+      && cp_parser_attributes_opt (parser)
+      && permerror (input_location,
+		    "attributes after parenthesized initializer ignored"))
+    {
+      static bool hint;
+      if (flag_permissive && !hint)
+	{
+	  hint = true;
+	  inform (input_location,
+		  "this flexibility is deprecated and will be removed");
+	}
+    }
 
   /* And now complain about a non-function implicit template.  */
   if (bogus_implicit_tmpl && decl != error_mark_node)
Index: doc/extend.texi
===================================================================
--- doc/extend.texi	(revision 258686)
+++ doc/extend.texi	(working copy)
@@ -23824,23 +23824,25 @@ some cases that the feature will be drop
 cases, the feature might be gone already.
 
 While the list below is not exhaustive, it documents some of the options
-that are now deprecated:
+that are now deprecated or have been removed:
 
 @table @code
 @item -fexternal-templates
 @itemx -falt-external-templates
-These are two of the many ways for G++ to implement template
-instantiation.  @xref{Template Instantiation}.  The C++ standard clearly
-defines how template definitions have to be organized across
-implementation units.  G++ has an implicit instantiation mechanism that
-should work just fine for standard-conforming code.
+These are two options provided alternative methods of template
+instantiation.  @xref{Template Instantiation}.  The options have been removed.
 
 @item -fstrict-prototype
 @itemx -fno-strict-prototype
 Previously it was possible to use an empty prototype parameter list to
 indicate an unspecified number of parameters (like C), rather than no
-parameters, as C++ demands.  This feature has been removed, except where
-it is required for backwards compatibility.   @xref{Backwards Compatibility}.
+parameters, as C++ demands.  This feature has been removed.
+
+@item -fno-for-scope
+@item -ffriend-injection
+These two options provide compatibility with pre-standard C++.
+@xref{Backwards Compatibility}.
+
 @end table
 
 G++ allows a virtual function returning @samp{void *} to be overridden
@@ -23879,6 +23881,14 @@ initializers for static members of const
 enumeration types so this extension has been deprecated and will be removed
 from a future version.
 
+G++ allows attributes to follow a parenthesized direct initializer,
+e.g.@: @samp{ int f (0) __attribute__ ((something)); } This extension
+has been ignored since G++ 3.3 and is deprecated.
+
+G++ allows anonymous structs and unions to have members that are not
+public non-static data members (i.e.@: fields).  These extensions are
+deprecated.
+
 @node Backwards Compatibility
 @section Backwards Compatibility
 @cindex Backwards Compatibility
Index: testsuite/g++.dg/ext/anon-struct6.C
===================================================================
--- testsuite/g++.dg/ext/anon-struct6.C	(revision 258686)
+++ testsuite/g++.dg/ext/anon-struct6.C	(working copy)
@@ -5,6 +5,6 @@ struct A
   struct
   {
     struct { static int i; }; // { dg-error "prohibits anonymous structs|non-static data members|unnamed class" }
-    void foo() { i; } // { dg-error "can only have non-static data" }
+    void foo() { i; } // { dg-error "public non-static data" }
   }; // { dg-error "prohibits anonymous structs" }
 };
Index: testsuite/g++.dg/ext/deprecate-1.C
===================================================================
--- testsuite/g++.dg/ext/deprecate-1.C	(revision 0)
+++ testsuite/g++.dg/ext/deprecate-1.C	(working copy)
@@ -0,0 +1,22 @@
+// be pickier about anon-union and structs
+// { dg-options "-fpermissive" }
+
+struct X
+{
+  struct 
+  {
+    int f1 (); // { dg-warning "public non-static data" }
+    // { dg-message "will be removed" "" { target *-*-* } .-1 }
+    typedef int t1;  // { dg-warning "public non-static data" }
+  private:
+    int m1; // { dg-warning "public non-static data" }
+  };
+
+  union
+  {
+    int f2 (); // { dg-warning "public non-static data" }
+    typedef int t2; // { dg-warning "public non-static data" }
+  protected:
+    int m2; // { dg-warning "public non-static data" }
+  };
+};
Index: testsuite/g++.dg/ext/deprecate-2.C
===================================================================
--- testsuite/g++.dg/ext/deprecate-2.C	(revision 0)
+++ testsuite/g++.dg/ext/deprecate-2.C	(working copy)
@@ -0,0 +1,4 @@
+// Stop accepting attributes after a parenthesized initializer
+// { dg-options "-fpermissive" }
+int i (0) __attribute__ ((ignored)); // { dg-warning "attributes" }
+// { dg-message "will be removed" "" { target *-*-* } .-1 }
Index: testsuite/g++.dg/lookup/pr84602.C
===================================================================
--- testsuite/g++.dg/lookup/pr84602.C	(revision 258686)
+++ testsuite/g++.dg/lookup/pr84602.C	(working copy)
@@ -3,7 +3,7 @@
 
 struct X {
   union {
-    class a; // { dg-warning "can only have" }
+    class a; // { dg-warning "public non-static data member" }
   };
   a *b;
 };
@@ -11,7 +11,7 @@ X::a *a;
 
 struct Y {
   union {
-    class a; // { dg-warning "can only have" }
+    class a; // { dg-warning "public non-static data member" }
     int a;
   };
   class a *b;
@@ -23,7 +23,7 @@ struct Z {
   union {
     // Force MEMBER_VEC creation
     int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
-    class a; // { dg-warning "can only have" }
+    class a; // { dg-warning "public non-static data member" }
     int a;
   };
   class a *b;
Index: testsuite/g++.dg/lookup/pr84962.C
===================================================================
--- testsuite/g++.dg/lookup/pr84962.C	(revision 258686)
+++ testsuite/g++.dg/lookup/pr84962.C	(working copy)
@@ -6,7 +6,7 @@ struct X {
   struct 
   {
     template <typename> int a ();
-    // { dg-error "can only have" "" { target *-*-* } .-1 }
+    // { dg-error "public non-static data member" "" { target *-*-* } .-1 }
   };
 
   int  : a; // { dg-error "non-integral" }
Index: testsuite/g++.old-deja/g++.other/anon4.C
===================================================================
--- testsuite/g++.old-deja/g++.other/anon4.C	(revision 258686)
+++ testsuite/g++.old-deja/g++.other/anon4.C	(working copy)
@@ -11,6 +11,6 @@ struct A
 {
   union
   {
-    void bad(); // { dg-error "can only have non-static data" }
+    void bad(); // { dg-error "public non-static data member" }
   };
 };

Reply via email to