diff mbox series

Deprecate some C++ extensions

Message ID a396e1bb-5ab4-e032-74be-68144ed307b7@acm.org
State New
Headers show
Series Deprecate some C++ extensions | expand

Commit Message

Nathan Sidwell March 20, 2018, 6:37 p.m. UTC
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

Comments

Sandra Loosemore March 20, 2018, 6:50 p.m. UTC | #1
On 03/20/2018 12:37 PM, Nathan Sidwell wrote:
> 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?

In general, I don't think the current GCC manual should document 
features that are no longer present in current GCC.  I've previously 
done a bunch of cleanups to other parts of the manual removing such bits 
for features that were documented as having gone away 10-20 years ago. 
:-P  So I think it is better to remove the documentation at the same 
time you remove the features, and mention the removal of the obsolete 
feature in the release notes instead of in the manual proper.

-Sandra
Gerald Pfeifer April 1, 2018, 5:32 p.m. UTC | #2
On Tue, 20 Mar 2018, Sandra Loosemore wrote:
> In general, I don't think the current GCC manual should document 
> features that are no longer present in current GCC.  I've previously 
> done a bunch of cleanups to other parts of the manual removing such bits 
> for features that were documented as having gone away 10-20 years ago. 
> :-P 
> So I think it is better to remove the documentation at the same time 
> you remove the features, and mention the removal of the obsolete feature 
> in the release notes instead of in the manual proper.

I was going to suggest that for things we believe may be in more
widely spread active use, keeping a brief note in the docs, but
looking at things from a decade ago, those surely do not qualify
for that. :-)

Gerald
diff mbox series

Patch

2018-03-20  Nathan Sidwell  <nathan@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" }
   };
 };