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)


[ CC'ing Sandra: since you were recently cleaning up the attributes docs
  (thanks), the doc/extend.texi bits in this patch might be of interest to
  you. ]

On Wed, May 06, 2015 at 08:44:10PM +0200, Marek Polacek wrote:
> 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

	Marek


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