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)


I'm pinging the C++ parts.

Thanks,

> On Thu, May 07, 2015 at 06:22:40PM +0200, Marek Polacek wrote:
> > This (third) version of the patch entails the change in tsubst_enum Ed
> > suggested + new testcase.
> > 
> > Bootstrapped/regtested on x86_64-linux, ok for trunk?
> > 
> > 2015-05-07  Marek Polacek  <polacek@redhat.com>
> > 	    Edward Smith-Rowland  <3dw4rd@verizon.net>
> > 
> > 	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 decl attributes 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.
> > 	* g++.dg/cpp1y/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..d5e2b56 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,
> > +			DECL_ATTRIBUTES (decl), 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..f143f15 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..fd1b6f0 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/47043
> > +// { 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;
> > +}
> > diff --git gcc/testsuite/g++.dg/cpp1y/attributes-enum-1.C gcc/testsuite/g++.dg/cpp1y/attributes-enum-1.C
> > index e69de29..3bd1ba1 100644
> > --- gcc/testsuite/g++.dg/cpp1y/attributes-enum-1.C
> > +++ gcc/testsuite/g++.dg/cpp1y/attributes-enum-1.C
> > @@ -0,0 +1,35 @@
> > +// PR c/47043
> > +// { dg-do compile { target c++14 } }
> > +
> > +class C
> > +{
> > +public:
> > +  enum Foo
> > +  {
> > +    T,
> > +    U [[deprecated("unused")]],
> > +    V
> > +  };
> > +};
> > +
> > +template<typename Tp>
> > +  class D
> > +  {
> > +  public:
> > +    enum Bar
> > +    {
> > +      X,
> > +      Y [[deprecated("unused")]],
> > +      Z
> > +    };
> > +  };
> > +
> > +int
> > +f (int i)
> > +{
> > +  auto j = C::U; // { dg-warning ".U. is deprecated" }
> > +
> > +  auto k = D<int>::Y; // { dg-warning ".Y. 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]