This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: C/C++ PATCH to allow deprecating enum values (PR c/47043)


On Wed, May 06, 2015 at 04:13:05PM +0000, Joseph Myers wrote:
> On Wed, 6 May 2015, Marek Polacek wrote:
> 
> > 2015-05-06  Marek Polacek  <polacek@redhat.com>
> > 
> > 	PR c/47043
> > 	* c-common.c (handle_deprecated_attribute): Allow CONST_DECL.
> 
> Do all other attributes already reject CONST_DECL?  I don't see any tests 
> for unsupported attributes on enum values being properly diagnosed (adding 
> tests for every unsupported attribute would seem excessive, but there 
> should be a few).

I've tried a bunch of them manually and all seemed to just ignore CONST_DECLs.
This version of the patch contains a new test to test invalid attributes.

> > diff --git gcc/c/c-parser.c gcc/c/c-parser.c
> > index bf0e4c57..f06a6b3 100644
> > --- gcc/c/c-parser.c
> > +++ gcc/c/c-parser.c
> > @@ -2584,7 +2584,11 @@ c_parser_enum_specifier (c_parser *parser)
> >  	  else
> >  	    enum_value = NULL_TREE;
> >  	  enum_decl = build_enumerator (decl_loc, value_loc,
> > -	      				&the_enum, enum_id, enum_value);
> > +					&the_enum, enum_id, enum_value);
> > +	  /* Parse any specified attributes.  */
> > +	  tree enum_attrs = c_parser_attributes (parser);
> > +	  if (enum_attrs)
> > +	    decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
> 
> You need to update the syntax comment to include the new syntax.  

Done (and for C++ as well).

> You also 
> need to update the user documentation of attributes (syntax and semantics) 
> in extend.texi to include this case.
 
Right, apparently I posted the patch too soon.  So this version updates
the documentation, hopefully what I wrote is enough.

> Why is the attribute going after the "= value"?  That seems inconsistent 
> with positioning of attributes in initialized variable declarations, for 
> example.

A thinko of mine: I didn't properly check what we do for variables with an
initializer...  Fixed by moving the attribute parsing slightly above.

Thanks.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2015-05-06  Marek Polacek  <polacek@redhat.com>

	PR c/47043
	* c-common.c (handle_deprecated_attribute): Allow CONST_DECL.

	* c-parser.c (c_parser_enum_specifier): Parse and apply enumerator
	attributes.

	* cp-tree.h (build_enumerator): Update declaration.
	* decl.c (build_enumerator): Add attributes parameter.  Call
	cplus_decl_attributes.
	* init.c (constant_value_1): Pass 0 to mark_used.
	* parser.c (cp_parser_enumerator_definition): Parse attributes and
	pass them down to build_enumerator.
	* pt.c (tsubst_enum): Pass NULL_TREE to build_enumerator.
	* semantics.c (finish_id_expression): Don't warn_deprecated_use here.

	* doc/extend.texi (Enumerator Attributes): New section.
	Document syntax of enumerator attributes.

	* c-c++-common/attributes-enum-1.c: New test.
	* c-c++-common/attributes-enum-2.c: New test.
	* g++.dg/cpp0x/attributes-enum-1.C: New test.

diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c
index ada8e8a..36968e5 100644
--- gcc/c-family/c-common.c
+++ gcc/c-family/c-common.c
@@ -8810,6 +8810,7 @@ handle_deprecated_attribute (tree *node, tree name,
 	  || TREE_CODE (decl) == VAR_DECL
 	  || TREE_CODE (decl) == FUNCTION_DECL
 	  || TREE_CODE (decl) == FIELD_DECL
+	  || TREE_CODE (decl) == CONST_DECL
 	  || objc_method_decl (TREE_CODE (decl)))
 	TREE_DEPRECATED (decl) = 1;
       else
diff --git gcc/c/c-parser.c gcc/c/c-parser.c
index bf0e4c57..889e6d7 100644
--- gcc/c/c-parser.c
+++ gcc/c/c-parser.c
@@ -2516,6 +2516,13 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
    enumerator:
      enumeration-constant
      enumeration-constant = constant-expression
+
+   GNU Extensions:
+
+   enumerator:
+     enumeration-constant attributes[opt]
+     enumeration-constant attributes[opt] = constant-expression
+
 */
 
 static struct c_typespec
@@ -2575,6 +2582,8 @@ c_parser_enum_specifier (c_parser *parser)
 	  c_parser_set_source_position_from_token (token);
 	  decl_loc = value_loc = token->location;
 	  c_parser_consume_token (parser);
+	  /* Parse any specified attributes.  */
+	  tree enum_attrs = c_parser_attributes (parser);
 	  if (c_parser_next_token_is (parser, CPP_EQ))
 	    {
 	      c_parser_consume_token (parser);
@@ -2584,7 +2593,9 @@ c_parser_enum_specifier (c_parser *parser)
 	  else
 	    enum_value = NULL_TREE;
 	  enum_decl = build_enumerator (decl_loc, value_loc,
-	      				&the_enum, enum_id, enum_value);
+					&the_enum, enum_id, enum_value);
+	  if (enum_attrs)
+	    decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
 	  TREE_CHAIN (enum_decl) = values;
 	  values = enum_decl;
 	  seen_comma = false;
diff --git gcc/cp/cp-tree.h gcc/cp/cp-tree.h
index e0fbf5e..6b26cb1 100644
--- gcc/cp/cp-tree.h
+++ gcc/cp/cp-tree.h
@@ -5400,7 +5400,7 @@ extern bool xref_basetypes			(tree, tree);
 extern tree start_enum				(tree, tree, tree, bool, bool *);
 extern void finish_enum_value_list		(tree);
 extern void finish_enum				(tree);
-extern void build_enumerator			(tree, tree, tree, location_t);
+extern void build_enumerator			(tree, tree, tree, tree, location_t);
 extern tree lookup_enumerator			(tree, tree);
 extern bool start_preparsed_function		(tree, tree, int);
 extern bool start_function			(cp_decl_specifier_seq *,
diff --git gcc/cp/decl.c gcc/cp/decl.c
index 261a12d..ebbd585 100644
--- gcc/cp/decl.c
+++ gcc/cp/decl.c
@@ -13067,11 +13067,12 @@ finish_enum (tree enumtype)
 
 /* Build and install a CONST_DECL for an enumeration constant of the
    enumeration type ENUMTYPE whose NAME and VALUE (if any) are provided.
-   LOC is the location of NAME.
+   Apply ATTRIBUTES if available.  LOC is the location of NAME.
    Assignment of sequential values by default is handled here.  */
 
 void
-build_enumerator (tree name, tree value, tree enumtype, location_t loc)
+build_enumerator (tree name, tree value, tree enumtype, tree attributes,
+		  location_t loc)
 {
   tree decl;
   tree context;
@@ -13234,6 +13235,9 @@ incremented enumerator value is too large for %<long%>");
   TREE_READONLY (decl) = 1;
   DECL_INITIAL (decl) = value;
 
+  if (attributes)
+    cplus_decl_attributes (&decl, attributes, 0);
+
   if (context && context == current_class_type && !SCOPED_ENUM_P (enumtype))
     /* In something like `struct S { enum E { i = 7 }; };' we put `i'
        on the TYPE_FIELDS list for `S'.  (That's so that you can say
diff --git gcc/cp/init.c gcc/cp/init.c
index c41e30c..9298f2d 100644
--- gcc/cp/init.c
+++ gcc/cp/init.c
@@ -2035,7 +2035,7 @@ constant_value_1 (tree decl, bool strict_p, bool return_aggregate_cst_ok_p)
 	 specialization, we must instantiate it here.  The
 	 initializer for the static data member is not processed
 	 until needed; we need it now.  */
-      mark_used (decl);
+      mark_used (decl, 0);
       mark_rvalue_use (decl);
       init = DECL_INITIAL (decl);
       if (init == error_mark_node)
diff --git gcc/cp/parser.c gcc/cp/parser.c
index 30a3fab..420759e 100644
--- gcc/cp/parser.c
+++ gcc/cp/parser.c
@@ -16056,7 +16056,13 @@ cp_parser_enumerator_list (cp_parser* parser, tree type)
      enumerator = constant-expression
 
    enumerator:
-     identifier  */
+     identifier
+
+   GNU Extensions:
+
+   enumerator-definition:
+     enumerator attributes [opt]
+     enumerator attributes [opt] = constant-expression  */
 
 static void
 cp_parser_enumerator_definition (cp_parser* parser, tree type)
@@ -16074,6 +16080,9 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type)
   if (identifier == error_mark_node)
     return;
 
+  /* Parse any specified attributes.  */
+  tree attrs = cp_parser_attributes_opt (parser);
+
   /* If the next token is an '=', then there is an explicit value.  */
   if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
     {
@@ -16091,7 +16100,7 @@ cp_parser_enumerator_definition (cp_parser* parser, tree type)
     value = error_mark_node;
 
   /* Create the enumerator.  */
-  build_enumerator (identifier, value, type, loc);
+  build_enumerator (identifier, value, type, attrs, loc);
 }
 
 /* Parse a namespace-name.
diff --git gcc/cp/pt.c gcc/cp/pt.c
index 8e0e789..c3a452d 100644
--- gcc/cp/pt.c
+++ gcc/cp/pt.c
@@ -20686,8 +20686,8 @@ tsubst_enum (tree tag, tree newtag, tree args)
       set_current_access_from_decl (decl);
 
       /* Actually build the enumerator itself.  */
-      build_enumerator
-	(DECL_NAME (decl), value, newtag, DECL_SOURCE_LOCATION (decl));
+      build_enumerator (DECL_NAME (decl), value, newtag, NULL_TREE,
+			DECL_SOURCE_LOCATION (decl));
     }
 
   if (SCOPED_ENUM_P (newtag))
diff --git gcc/cp/semantics.c gcc/cp/semantics.c
index 701a8eb..b46c6fc 100644
--- gcc/cp/semantics.c
+++ gcc/cp/semantics.c
@@ -3651,11 +3651,6 @@ finish_id_expression (tree id_expression,
 	}
     }
 
-  /* Handle references (c++/56130).  */
-  tree t = REFERENCE_REF_P (decl) ? TREE_OPERAND (decl, 0) : decl;
-  if (TREE_DEPRECATED (t))
-    warn_deprecated_use (t, NULL_TREE);
-
   return decl;
 }
 
diff --git gcc/doc/extend.texi gcc/doc/extend.texi
index c290059..4337a32 100644
--- gcc/doc/extend.texi
+++ gcc/doc/extend.texi
@@ -59,6 +59,7 @@ extensions, accepted by GCC in C90 mode and in C++.
 * Variable Attributes:: Specifying attributes of variables.
 * Type Attributes::     Specifying attributes of types.
 * Label Attributes::    Specifying attributes on labels.
+* Enumerator Attributes:: Specifying attributes on enumerators.
 * Attribute Syntax::    Formal syntax for attributes.
 * Function Prototypes:: Prototype declarations and old-style definitions.
 * C++ Comments::        C++ comments are recognized.
@@ -2175,6 +2176,7 @@ attribute syntax and placement.
 GCC also supports attributes on
 variable declarations (@pxref{Variable Attributes}),
 labels (@pxref{Label Attributes}),
+enumerators (@pxref{Enumerator Attributes}),
 and types (@pxref{Type Attributes}).
 
 There is some overlap between the purposes of attributes and pragmas
@@ -5041,8 +5043,9 @@ by an attribute specification inside double parentheses.  Some
 attributes are currently defined generically for variables.
 Other attributes are defined for variables on particular target
 systems.  Other attributes are available for functions
-(@pxref{Function Attributes}), labels (@pxref{Label Attributes}) and for 
-types (@pxref{Type Attributes}).
+(@pxref{Function Attributes}), labels (@pxref{Label Attributes}),
+enumerators (@pxref{Enumerator Attributes}), and for types
+(@pxref{Type Attributes}).
 Other front ends might define more attributes
 (@pxref{C++ Extensions,,Extensions to the C++ Language}).
 
@@ -5837,7 +5840,8 @@ attributes of types.  Some type attributes apply only to @code{struct}
 and @code{union} types, while others can apply to any type defined
 via a @code{typedef} declaration.  Other attributes are defined for
 functions (@pxref{Function Attributes}), labels (@pxref{Label 
-Attributes}) and for variables (@pxref{Variable Attributes}).
+Attributes}), enumerators (@pxref{Enumerator Attributes}), and for
+variables (@pxref{Variable Attributes}).
 
 The @code{__attribute__} keyword is followed by an attribute specification
 inside double parentheses.  
@@ -6300,7 +6304,8 @@ compilers to match the native Microsoft compiler.
 GCC allows attributes to be set on C labels.  @xref{Attribute Syntax}, for 
 details of the exact syntax for using attributes.  Other attributes are 
 available for functions (@pxref{Function Attributes}), variables 
-(@pxref{Variable Attributes}) and for types (@pxref{Type Attributes}).
+(@pxref{Variable Attributes}), enumerators (@xref{Enumerator Attributes}),
+and for types (@pxref{Type Attributes}).
 
 This example uses the @code{cold} label attribute to indicate the 
 @code{ErrorHandling} branch is unlikely to be taken and that the
@@ -6346,6 +6351,45 @@ with computed goto or @code{asm goto}.
 
 @end table
 
+@node Enumerator Attributes
+@section Enumerator Attributes
+@cindex Enumerator Attributes
+
+GCC allows attributes to be set on enumerators.  @xref{Attribute Syntax}, for
+details of the exact syntax for using attributes.  Other attributes are
+available for functions (@pxref{Function Attributes}), variables
+(@pxref{Variable Attributes}), labels (@xref{Label Attributes}),
+and for types (@pxref{Type Attributes}).
+
+This example uses the @code{deprecated} enumerator attribute to indicate the
+@code{oldval} enumerator is deprecated:
+
+@smallexample
+enum E @{
+  oldval __attribute__((deprecated)),
+  newval
+@};
+
+int
+fn (void)
+@{
+  return oldval;
+@}
+@end smallexample
+
+@table @code
+@item deprecated
+@cindex @code{deprecated} enumerator attribute
+The @code{deprecated} attribute results in a warning if the enumerator
+is used anywhere in the source file.  This is useful when identifying
+enumerators that are expected to be removed in a future version of a
+program.  The warning also includes the location of the declaration
+of the deprecated enumerator, to enable users to easily find further
+information about why the enumerator is deprecated, or what they should
+do instead.  Note that the warnings only occurs for uses.
+
+@end table
+
 @node Attribute Syntax
 @section Attribute Syntax
 @cindex attribute syntax
@@ -6371,6 +6415,8 @@ for details of the semantics of attributes applying to structure, union
 and enumerated types.
 @xref{Label Attributes}, for details of the semantics of attributes 
 applying to labels.
+@xref{Enumerator Attributes}, for details of the semantics of attributes
+applying to enumerators.
 
 An @dfn{attribute specifier} is of the form
 @code{__attribute__ ((@var{attribute-list}))}.  An @dfn{attribute list}
@@ -6428,6 +6474,14 @@ ambiguous, as it is permissible for a declaration, which could begin
 with an attribute list, to be labelled in C++.  Declarations cannot be
 labelled in C90 or C99, so the ambiguity does not arise there.
 
+@subsubheading Enumerator Attributes
+
+In GNU C, an attribute specifier list may appear as part of an enumerator.
+The attribute goes after the enumeration constant, before @code{=}, if
+present.  The optional attribute in the enumerator appertains to the
+enumeration constant.  It is not possible to place the attribute after
+the constant expression, if present.
+
 @subsubheading Type Attributes
 
 An attribute specifier list may appear as part of a @code{struct},
diff --git gcc/testsuite/c-c++-common/attributes-enum-1.c gcc/testsuite/c-c++-common/attributes-enum-1.c
index e69de29..cb5af5b 100644
--- gcc/testsuite/c-c++-common/attributes-enum-1.c
+++ gcc/testsuite/c-c++-common/attributes-enum-1.c
@@ -0,0 +1,22 @@
+/* Test enumerators with attributes.  */
+/* PR c/47043 */
+/* { dg-do compile } */
+
+enum E {
+  A __attribute__((deprecated)),
+  B __attribute__((deprecated ("foo"))),
+  C __attribute__((deprecated)) = 10,
+  D __attribute__((deprecated ("foo"))) = 15,
+  E
+};
+
+int
+f (int i)
+{
+  i += A; /* { dg-warning ".A. is deprecated" } */
+  i += B; /* { dg-warning ".B. is deprecated" } */
+  i += C; /* { dg-warning ".C. is deprecated" } */
+  i += D; /* { dg-warning ".D. is deprecated" } */
+  i += E;
+  return i;
+}
diff --git gcc/testsuite/c-c++-common/attributes-enum-2.c gcc/testsuite/c-c++-common/attributes-enum-2.c
index e69de29..df5bc9c 100644
--- gcc/testsuite/c-c++-common/attributes-enum-2.c
+++ gcc/testsuite/c-c++-common/attributes-enum-2.c
@@ -0,0 +1,14 @@
+/* Test enumerators with attributes.  Test invalid uses.  */
+/* PR c/47043 */
+/* { dg-do compile } */
+
+enum E {
+  A __attribute__((foo)),	/* { dg-warning "ignored" } */
+  B __attribute__((cold)),	/* { dg-warning "ignored" } */
+  C __attribute__((const)),	/* { dg-warning "ignored" } */
+  D __attribute__((unused)),	/* { dg-warning "ignored" } */
+  E __attribute__((flatten)),	/* { dg-warning "ignored" } */
+  F __attribute__((tm)),	/* { dg-warning "ignored" } */
+  G __attribute__((common)),	/* { dg-warning "ignored" } */
+  H __attribute__((volatile)),	/* { dg-warning "ignored" } */
+};
diff --git gcc/testsuite/g++.dg/cpp0x/attributes-enum-1.C gcc/testsuite/g++.dg/cpp0x/attributes-enum-1.C
index e69de29..4146116 100644
--- gcc/testsuite/g++.dg/cpp0x/attributes-enum-1.C
+++ gcc/testsuite/g++.dg/cpp0x/attributes-enum-1.C
@@ -0,0 +1,20 @@
+// PR c/47046
+// { dg-do compile { target c++11 } }
+
+enum E {
+  A [[gnu::deprecated]]
+};
+
+enum class F {
+  B [[gnu::deprecated]],
+  C __attribute__ ((deprecated))
+};
+
+int
+f (int i)
+{
+  F f1 = F::B; // { dg-warning ".B. is deprecated" }
+  F f2 = F::C; // { dg-warning ".C. is deprecated" }
+  i += A; // { dg-warning ".A. is deprecated" }
+  return i;
+}

	Marek


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]